/metabase-data-app-setup
Scaffold a new Metabase data-app into the connected remote-sync repository's `data_apps/<app>/` directory from the `data-app-template`. Use when the user asks to start, create, scaffold, or set up a data-app from scratch.
$ npx -y skills add metabase/metabase --skill metabase-data-app-setup --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/metabase-data-app-setup
Context preview
The summary Claude sees to decide when to auto-load this skill.
Scaffold a new Metabase data-app into the connected remote-sync repository's `data_apps/<app>/` directory from the `data-app-template`. Use when the user asks to start, create, scaffold, or set up a data-app from scratch.
SKILL.md
metabase-data-app-setup.SKILL.mdname: metabase-data-app-setup
description: Scaffold a new Metabase data-app into the connected remote-sync repository's `data_apps/<app>/` directory from the `data-app-template`. Use when the user asks to start, create, scaffold, or set up a data-app from scratch.
Create a Metabase Data App
A Metabase **data-app** is a single JS bundle that the host loads inside a Near Membrane sandbox and renders inside its own React tree. The scaffold is a Vite + React + TypeScript project: source under `src/`, a dev server that previews the app against a real Metabase **through the same Near Membrane sandbox + distortion rules Metabase uses in production** — so `npm run dev` behaves like production, including for third-party libraries the app bundles — and `npm run build` producing a single `dist/index.js`. (Because the sandbox runs a built bundle, a change rebuilds it and does a *soft reload* — re-evaluates the bundle in the sandbox and remounts the app, keeping auth/SDK loaded — rather than hot-swapping modules; component state resets, but there's no full browser refresh.) The dev preview also shows a corner **⚠ Diagnostics** toolbar that captures runtime errors — including the sandbox's otherwise-opaque blocked-API messages — so failures surface instead of being swallowed. The same data is served as JSON at `http://localhost:5174/__data-app/diagnostics`, which is how *you* read it (see "Reading the diagnostics feed" below) — you have a shell, not a browser, and these failures are invisible from the terminal otherwise.
**Data apps are served from Git, not uploaded.** A single repository is connected to Metabase via remote-sync (Admin → Settings → Remote sync). Each app lives in its own directory `data_apps/<app>/` inside that repo — its source, a `data_app.yaml` (name/path), and the committed built bundle at the `path` its `data_app.yaml` declares (`dist/index.js` by default). On each remote-sync import Metabase materializes one app per directory and serves it at `/apps/<slug>` url, where the slug **is** the directory's name. So this skill always scaffolds **into the connected repo's `data_apps/<app>/` directory**, never as a standalone project.
**The scaffold ships inside this skill at `./template/`** — a Vite + React + TypeScript project that was installed alongside the skill. Step 3 just copies it into the app directory; the skill then guides you through the customization + first-app-content steps — it never generates project files from scratch. If you find yourself writing `package.json`, `vite.config.ts`, `tsconfig.json`, or `src/index.tsx` by hand, stop — copy the template instead.
When to invoke this skill
- "scaffold a new data app" / "create a Metabase data app" / "set up a data-app project"
- "I want to build a data app" / any vague intent to author a data app
- Starting a fresh agent task that will produce a data-app bundle.
- Do **not** use this skill for an existing data-app project when the task is to
build screens, use Metabase data, generate or refresh schema files, wire saved questions / tables / metrics / actions, add filters, or author data hooks. Treat those as existing-data-app editing tasks and use the agent's normal skill-discovery flow from the user's wording.
Step 1 — Locate the remote-sync repository
Data apps live inside the Git repository connected to Metabase via remote-sync. Find it before scaffolding:
- Ask: **"Do you already have a Git repository connected to this Metabase via remote-sync?"**
- **Yes** → ask for its local path.
- **No** → ask the user to **create one** (a plain Git repo they will connect under Admin → Settings → Remote sync) and share its path. The skill does **not** create or connect the repo — the user owns that.
- Verify the path exists and is a Git working tree (it has a `.git`). This repo is the working directory for every step below.
Step 2 — Name the app and create its directory
1. Settle on the app's **directory name** before scaffolding — it is used verbatim as the slug (the `/apps/<slug>` URL), so it **must be dash-cased**: lowercase letters, numbers, and single dashes (`[a-z0-9]+(?:-[a-z0-9]+)*`), e.g. `sales-overview`. Anything else (uppercase, spaces, underscores) is rejected on sync. If the purpose isn't clear yet, ask a one-line "what's this app for?" and propose a name; confirm it. 2. Ensure `<repo>/data_apps/` exists; create it if missing. 3. Create `<repo>/data_apps/<slug>/`. **If it already exists**, treat it as an existing project (see below) — never overwrite without confirmation.
Detecting an existing app
If `<repo>/data_apps/<slug>/` already holds a project, verify it matches the current `data-app-template`. Check **all** of:
1. `vite.config.ts` is a one-liner: `export default dataAppConfig()` (from `@metabase/embedding-sdk-react/data-app-dev/config`). There is **no** local `config/` directory: the whole bundle contract (externals/globals, the dev sandbox entry, CSS/SVG handling) lives inside that SDK config, not the scaffold. `dataAppConfig` takes only a curated set of overrides (currently just `port`); the contract plugin is always applied and can't be overridden. 2. `src/index.tsx` default-exports a `DataAppFactory` (type from `@metabase/embedding-sdk-react/data-app`) returning `{ component, providerProps? }` (no args).
**All checks pass** → template-shaped. Ask: "Extend this app, or scaffold a new one under a different slug?" If extend → skip the copy step, edit `src/`. If new → pick a different slug and restart at Step 2.
**Any check fails** → not template-shaped (older scaffold or drift). **Stop.** Tell the user the structure differs from the current template, extending it risks breaking the bundle contract, and ask whether to (1) migrate it, (2) scaffold fresh under a new slug and port the code over, or (3) proceed anyway at their risk. Wait for the answer.
Never overwrite existing files without explicit confirmation.
Step 3 — Copy the template i
Read more
name: metabase-data-app-setup description: Scaffold a new Metabase data-app into the connected remote-sync repository's `data_apps/<app>/` directory from the `data-app-template`. Use when the user asks to start, create, scaffold, or set up a data-app from scratch.
Create a Metabase Data App
A Metabase **data-app** is a single JS bundle that the host loads inside a Near Membrane sandbox and renders inside its own React tree. The scaffold is a Vite + React + TypeScript project: source under `src/`, a dev server that previews the app against a real Metabase **through the same Near Membrane sandbox + distortion rules Metabase uses in production** — so `npm run dev` behaves like production, including for third-party libraries the app bundles — and `npm run build` producing a single `dist/index.js`. (Because the sandbox runs a built bundle, a change rebuilds it and does a *soft reload* — re-evaluates the bundle in the sandbox and remounts the app, keeping auth/SDK loaded — rather than hot-swapping modules; component state resets, but there's no full browser refresh.) The dev preview also shows a corner **⚠ Diagnostics** toolbar that captures runtime errors — including the sandbox's otherwise-opaque blocked-API messages — so failures surface instead of being swallowed. The same data is served as JSON at `http://localhost:5174/__data-app/diagnostics`, which is how *you* read it (see "Reading the diagnostics feed" below) — you have a shell, not a browser, and these failures are invisible from the terminal otherwise.
**Data apps are served from Git, not uploaded.** A single repository is connected to Metabase via remote-sync (Admin → Settings → Remote sync). Each app lives in its own directory `data_apps/<app>/` inside that repo — its source, a `data_app.yaml` (name/path), and the committed built bundle at the `path` its `data_app.yaml` declares (`dist/index.js` by default). On each remote-sync import Metabase materializes one app per directory and serves it at `/apps/<slug>` url, where the slug **is** the directory's name. So this skill always scaffolds **into the connected repo's `data_apps/<app>/` directory**, never as a standalone project.
**The scaffold ships inside this skill at `./template/`** — a Vite + React + TypeScript project that was installed alongside the skill. Step 3 just copies it into the app directory; the skill then guides you through the customization + first-app-content steps — it never generates project files from scratch. If you find yourself writing `package.json`, `vite.config.ts`, `tsconfig.json`, or `src/index.tsx` by hand, stop — copy the template instead.
When to invoke this skill
- "scaffold a new data app" / "create a Metabase data app" / "set up a data-app project"
- "I want to build a data app" / any vague intent to author a data app
- Starting a fresh agent task that will produce a data-app bundle.
- Do **not** use this skill for an existing data-app project when the task is to
build screens, use Metabase data, generate or refresh schema files, wire saved questions / tables / metrics / actions, add filters, or author data hooks. Treat those as existing-data-app editing tasks and use the agent's normal skill-discovery flow from the user's wording.
Step 1 — Locate the remote-sync repository
Data apps live inside the Git repository connected to Metabase via remote-sync. Find it before scaffolding:
- Ask: **"Do you already have a Git repository connected to this Metabase via remote-sync?"**
- **Yes** → ask for its local path.
- **No** → ask the user to **create one** (a plain Git repo they will connect under Admin → Settings → Remote sync) and share its path. The skill does **not** create or connect the repo — the user owns that.
- Verify the path exists and is a Git working tree (it has a `.git`). This repo is the working directory for every step below.
Step 2 — Name the app and create its directory
1. Settle on the app's **directory name** before scaffolding — it is used verbatim as the slug (the `/apps/<slug>` URL), so it **must be dash-cased**: lowercase letters, numbers, and single dashes (`[a-z0-9]+(?:-[a-z0-9]+)*`), e.g. `sales-overview`. Anything else (uppercase, spaces, underscores) is rejected on sync. If the purpose isn't clear yet, ask a one-line "what's this app for?" and propose a name; confirm it. 2. Ensure `<repo>/data_apps/` exists; create it if missing. 3. Create `<repo>/data_apps/<slug>/`. **If it already exists**, treat it as an existing project (see below) — never overwrite without confirmation.
Detecting an existing app
If `<repo>/data_apps/<slug>/` already holds a project, verify it matches the current `data-app-template`. Check **all** of:
1. `vite.config.ts` is a one-liner: `export default dataAppConfig()` (from `@metabase/embedding-sdk-react/data-app-dev/config`). There is **no** local `config/` directory: the whole bundle contract (externals/globals, the dev sandbox entry, CSS/SVG handling) lives inside that SDK config, not the scaffold. `dataAppConfig` takes only a curated set of overrides (currently just `port`); the contract plugin is always applied and can't be overridden. 2. `src/index.tsx` default-exports a `DataAppFactory` (type from `@metabase/embedding-sdk-react/data-app`) returning `{ component, providerProps? }` (no args).
**All checks pass** → template-shaped. Ask: "Extend this app, or scaffold a new one under a different slug?" If extend → skip the copy step, edit `src/`. If new → pick a different slug and restart at Step 2.
**Any check fails** → not template-shaped (older scaffold or drift). **Stop.** Tell the user the structure differs from the current template, extending it risks breaking the bundle contract, and ask whether to (1) migrate it, (2) scaffold fresh under a new slug and port the code over, or (3) proceed anyway at their risk. Wait for the answer.
Never overwrite existing files without explicit confirmation.
Step 3 — Copy the template i
Metabase is the easy, open-source way for everyone in your company to ask questions and learn from data.
Repo: metabase/metabase
Other skills on metabase.
- /add-malli-schemas
Efficiently add Malli schemas to API endpoints in the Metabase codebase with proper patterns, validation timing, and error handling
Open skill - /add-tracing
Add OpenTelemetry tracing spans to Clojure code following Metabase tracing conventions. Use when instrumenting backend code with trace coverage.
Open skill - /analytics-events
Add product analytics events to track user interactions in the Metabase frontend
Open skill - /clojure-eval
Evaluate Clojure code via nREPL using clj-nrepl-eval. Use this when you need to test code, check if edited files compile, verify function behavior, or interact with a running REPL session.
Open skill - /clojure-review
Review Clojure and ClojureScript code changes for compliance with Metabase coding standards, style violations, and code quality issues. Use when reviewing pull requests or diffs containing Clojure/ClojureScript code.
Open skill - /clojure-write
Guide Clojure and ClojureScript development using REPL-driven workflow, coding conventions, and best practices. Use when writing, developing, or refactoring Clojure/ClojureScript code.
Open skill

