New Project
Next.js template for user-defined, AI-powered analytics UIs using MotherDuck embedded Dives.
Dives are code-based, fully customizable React components that can query MotherDuck, a serverless cloud data warehouse powered by DuckDB. Dives lets you build interactive dashboards, presentations, or even data-driven games, all fetching live data through SQL queries. Embedded in your app, Dives give you infinite flexibility over how data is presented, without the constraints of traditional BI tools.
This template gives you a deployable Next.js app where users can browse starter Dives, open full-page previews, and use AI chat to customize a Dive in place.
Demo auth note: included auth is for demo purposes. For production use cases, connect your own identity provider and authorization model before shipping.
Click Deploy with Vercel. The clone flow provisions:
MOTHERDUCK_TOKENPOSTGRES_URLmigrations/If you do not install either integration, set the matching environment variable yourself before deploying.
After deploy, add at least one AI key in Vercel project settings, then redeploy:
ANTHROPIC_API_KEYOPENAI_API_KEYAI_GATEWAY_API_KEYManual deploy:
vercel linkvercel env pull .env.localvercel deploy
git clone <your-repo-url>cd motherduck-divesnpm installcp .env.example .env.local
Run local Postgres:
docker run --name motherduck-dives-postgres \-e POSTGRES_PASSWORD=postgres \-e POSTGRES_DB=motherduck_dives \-p 5433:5432 \-d postgres:16
Set local database URL:
POSTGRES_URL=postgres://postgres:postgres@localhost:5433/motherduck_dives
Start app:
npm run dev
Open http://localhost:3000, choose a Dive, click Remix, and chat.
Useful commands:
npm run lintnpm exec tsc -- --noEmitnpm run buildnpm run build:with-migrate
| Variable | Required | Description |
|---|---|---|
MOTHERDUCK_TOKEN | Yes | MotherDuck admin token used to provision service accounts and embed sessions |
POSTGRES_URL | Yes | Postgres connection string |
ANTHROPIC_API_KEY | One AI key required | Anthropic API key |
OPENAI_API_KEY | One AI key required | OpenAI API key |
AI_GATEWAY_API_KEY | One AI key required | Vercel AI Gateway API key |
AI_MODEL_ANTHROPIC | No | Anthropic model override, defaults to claude-sonnet-4-6 |
AI_MODEL_OPENAI | No | OpenAI model override, defaults to gpt-5.4 |
AI_MODEL_GATEWAY | No | AI Gateway model override, defaults to anthropic/claude-sonnet-4.6 |
Advanced overrides:
| Variable | Required | Description |
|---|---|---|
MOTHERDUCK_API_BASE | No | MotherDuck API URL override |
MOTHERDUCK_MCP_URL | No | MotherDuck MCP endpoint override |
MOTHERDUCK_PG_HOST | No | MotherDuck Postgres endpoint host override |
Default mode is public demo mode. Visitors can preview shared starter Dives. First edit creates an isolated anonymous MotherDuck service account and cloned starter Dives for that browser session.
Password mode requires sign-in and uses one shared MotherDuck service account:
PASSWORD_AUTH_ENABLED=trueAUTH_SECRET=<long-random-string>MOTHERDUCK_SHARED_SERVICE_ACCOUNT_USERNAME=app_shared
Personal token mode requires sign-in and asks each user for their own MotherDuck personal access token:
PASSWORD_AUTH_ENABLED=trueAUTH_SECRET=<long-random-string>MOTHERDUCK_AUTH_MODE=personal_patMOTHERDUCK_PAT_ENCRYPTION_KEY=<long-random-string>
Auth mode options:
PASSWORD_AUTH_ENABLED: set to true to require email/password sign-in.AUTH_SECRET: required when password auth is enabled. Use a long random string for NextAuth session signing.MOTHERDUCK_SHARED_SERVICE_ACCOUNT_USERNAME: optional shared MotherDuck service account username. Defaults to app_shared.MOTHERDUCK_AUTH_MODE: set to personal_pat to require each signed-in user to provide a MotherDuck PAT.MOTHERDUCK_PAT_ENCRYPTION_KEY: required when MOTHERDUCK_AUTH_MODE=personal_pat. Use a long random string to encrypt stored MotherDuck PATs.MOTHERDUCK_TOKEN_APP_NAME: optional app name shown on the MotherDuck token request page. Defaults to motherduck-dives.AUTH_TRUSTED_ORIGINS: optional comma-separated scheme://host[:port] values allowed for mutating requests behind proxies or custom origins.Edit starter Dive components:
dives/presentation-dive.tsxdives/dashboard-dive.tsxdives/game-dive.tsxStarter metadata lives in app/_lib/dive-provisioning.ts.
app/_lib/chat/ai-provider.ts or set model env vars.app/_lib/chat/system-prompt.ts.Starter Dives use MotherDuck sample_data. To use your own data:
assertSameOrigin(request) on every mutating route.MIT