Data App Creator
SkillFiles & storageCreate self-contained HTML apps from user data (CSV, JSON, bank statements, APIs) with interactive tables and charts.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Data App Creator skill
What this skill tells your AI
The instructions your AI receives, as published by spamsch/son-of-simon in skills/data_app_creator/SKILL.md and read by ahel’s review.
Behavior Notes
When to Use This Skill
Use this skill when the user wants a persistent, visual app they can open and interact with in a browser. Examples: dashboards, data explorers, chart viewers, interactive tables.
Do NOT use this skill when the user just wants quick analysis or a one-off answer ("what's my average spending?"). For that, use Python or shell commands directly and report the result.
Rule of thumb: If the user says "create", "build", "make", "dashboard", or "app" — use this skill. If they say "analyze", "tell me", "what is" — just answer the question.
The App Creation Workflow
- Understand what the user wants to see — ask for clarification if the request is vague
- Locate data — use
spotlight_searchto find files,read_fileto load them, orweb_fetch/fetch_urlfor API data - Analyze structure — peek at the first 5–10 rows, detect column names, types, and value ranges
- Choose app type — dashboard, table viewer, chart, or API-driven (see Common App Types below)
- Generate HTML — a single self-contained HTML file following the structure template below
- Save to the
appswell-known directory under a descriptive subfolder:<apps-dir>/<descriptive-name>/index.html - Open in Safari with
open -a Safari <path>
Always use get_preferences to resolve the apps directory path — never hardcode ~/Documents/Apps.
App Directory Convention
Each app lives in its own subfolder under the apps well-known directory:
~/Documents/Apps/
bank-statement-2024/
index.html
weather-dashboard/
index.html
data.json (only for large datasets)
- Kebab-case folder names — descriptive, no generic names like "dashboard"
- Always
index.htmlas the entry point - One app per folder — keeps things tidy for the user
Data Processing Patterns
CSV files — embed as a JS string constant, parse client-side with PapaParse:
<script src="https://cdn.jsdelivr.net/npm/papaparse@5/papaparse.min.js"></script>
<script>
const csvData = `...embedded CSV...`;
const parsed = Papa.parse(csvData, { header: true, dynamicTyping: true });
</script>
JSON files — embed directly as a JS object literal:
<script>
const data = [ ...embedded JSON... ];
</script>
API data — use client-side fetch() with loading states and error handling:
<script>
async function loadData() {
showLoading();
try {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
renderDashboard(data);
} catch (err) {
showError('Failed to load data. Check your connection and try again.');
}
}
</script>
Large data (>500KB) — save as a separate data.json in the same folder, fetch it via a relative path:
<script>
fetch('data.json').then(r => r.json()).then(renderDashboard);
</script>
HTML Structure Template
Every generated app should follow this base skeleton:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>App Title</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
background: #f5f5f7;
color: #1d1d1f;
padding: 24px;
line-height: 1.5;
}
@media (prefers-color-scheme: dark) {
body { background: #1d1d1f; color: #f5f5f7; }
.card { background: #2c2c2e; }
}
h1 { font-size: 28px; font-weight: 700; margin-bottom: 24px; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 16px;
margin-bottom: 24px;
}
.card {
background: #fff;
border-radius: 12px;
padding: 20px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.card h2 { font-size: 14px; color: #86868b; font-weight: 500; margin-bottom: 4px; }
.card .value { font-size: 32px; font-weight: 700; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #e5e5ea; }
th { font-weight: 600; font-size: 13px; color: #86868b; text-transform: uppercase; letter-spacing: 0.5px; }
@media (prefers-color-scheme: dark) {
th, td { border-color: #3a3a3c; }
}
</style>
</head>
<body>
<h1>App Title</h1>
<div class="grid">
<!-- Summary cards -->
</div>
<!-- Charts -->
<!-- Detail table -->
<script>
// Data and rendering logic
</script>
</body>
</html>
Layout pattern: Summary cards at top → charts in the middle → detail table at the bottom.
Recommended Libraries
Load from CDN — keeps apps self-contained with no build step:
- Chart.js — default choice for line, bar, pie, and doughnut charts. Simple API, looks good out of the box.
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script> - PapaParse — CSV parsing. Always use
header: trueanddynamicTyping: true.<script src="https://cdn.jsdelivr.net/npm/papaparse@5/papaparse.min.js"></script> - Plotly.js — use only when the user needs advanced interactivity (3D charts, hover details, range sliders). Heavier than Chart.js.
<script src="https://cdn.jsdelivr.net/npm/plotly.js@2/dist/plotly.min.js"></script> - Vanilla JS tables — for simple data with <100 rows, skip libraries entirely. Add sort/filter with plain JS event handlers.
Common App Types
Financial dashboard (bank statements, expense exports):
- Auto-detect date, amount, and description/category columns
- Summary cards: total income, total expenses, net, transaction count
- Chart: spending over time (grouped by month or week)
- Chart: spending by category (pie or bar)
- Table: all transactions, sortable by date/amount
- Format amounts with currency symbols and 2 decimal places
Generic CSV explorer (any tabular data):
- Sortable, filterable table with all columns
- Column statistics at top: count, min, max, mean for numeric columns
- Search/filter input above the table
- Handle missing values gracefully — show "—" not "null"
API dashboard (weather, stocks, public APIs):
- Loading spinner while fetching
- Auto-refresh with configurable interval (default: 5 minutes)
- Error state with retry button
- Last-updated timestamp in the header
- Use
fetch()with timeout handling
Health data viewer (Apple Health exports, fitness data):
- Time-series line charts with date range controls
- Summary stats per period (daily, weekly, monthly)
- Multiple metrics on the same chart where it makes sense
Styling Defaults
- Font:
-apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif - Spacing: multiples of 8px (8, 16, 24, 32)
- Colors: light background
#f5f5f7, white cards#fff, dark text#1d1d1f, muted labels#86868b - Dark mode: always include
@media (prefers-color-scheme: dark)with inverted backgrounds and lighter text - Responsive: use
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))for card layouts - Border radius: 12px for cards, 8px for inputs/buttons
- Shadows: subtle
box-shadow: 0 1px 3px rgba(0,0,0,0.08)on cards
Smart Data Detection
Use these heuristics to pick the right visualization automatically:
- Date column + number column → line chart (time series)
- Category column + number column → bar chart or pie chart
- Financial keywords in filename or headers (amount, balance, debit, credit, transaction) → financial dashboard layout
- All text columns → searchable/sortable table, no charts
- Lat/lng columns → mention map possibility but stick to table (maps need Leaflet, which adds complexity)
- Multiple numeric columns → summary stats cards + comparison bar chart
Security & Privacy
- Confirm before embedding account numbers, SSNs, or other PII in the HTML file
- Redact sensitive fields to last-4 digits when displaying (e.g.,
****1234) - Warn the user that HTML files store data in plain text — anyone with file access can read them
- Never embed API keys in client-side code — use public/free-tier APIs or prompt the user to enter keys at runtime
- Sanitize data before injecting into HTML to prevent XSS (escape
<,>,&,",'in user data strings)
Signals
- GitHub stars
- 28
- Forks
- 1
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
data-app-creator- Source
- github.com/spamsch/son-of-simon