Production-ready Next.js + Postgres starter for AI apps. Zero-downtime migrations, instant database branches, PII-safe prod clones, and 6 Claude Code skills.
- ⚡ Zero-downtime migrations with pgroll's expand-contract pattern (old and new schemas serve traffic simultaneously)
- 🌳 Instant database branches via copy-on-write (ready in seconds, no storage duplication)
- 🔒 Anonymized production clones with referential integrity preserved across foreign keys
- 🤖 6 Claude Code skills for branch, migrate, clone, and rollback workflows
- 🐘 Next.js 14 + raw Postgres (no ORM, raw
postgresdriver) - 📦 MIT licensed, ready to fork
Open Claude Code in this directory and use these slash commands, or describe the workflow in plain English and Claude Code will run the right Xata CLI sequence.
| Command | Description |
|---|---|
/project:setup |
Connect to Xata and configure the project |
/project:branch-create |
Create an isolated database branch |
/project:migration-start |
Start a zero-downtime migration |
/project:migration-complete |
Complete an ongoing migration |
/project:migration-rollback |
Roll back a failed migration |
/project:clone-production |
Clone production with PII anonymization |
Claude Code running /branch-create: names the branch, creates it, waits for ready, and returns the connection string.
The skills are markdown files in .claude/skills/. Fork them, extend them, or write your own for other workflows.
- Node.js 18+
- A Xata account
- Xata CLI installed
git clone https://github.com/xataio/nextjs-claude-code-starter
cd nextjs-claude-code-starter
npm installcurl -fsSL https://xata.io/install.sh | bash
export PATH="$HOME/.config/xata/bin:$PATH"xata auth login
xata initFollow the prompts to select your organization, project, and branch.
xata branch url
# Copy the connection string
cp .env.example .env.local
# Open .env.local and paste the connection string as the value of DATABASE_URLxata roll init
xata roll start migrations/001_create_users.yaml
xata roll complete
xata roll start migrations/002_add_role.yaml
xata roll complete
xata roll start migrations/003_add_teams.yaml
xata roll completeroll init is a one-time setup. Each roll start begins the expand phase (both old and new schemas serve traffic), and roll complete runs the contract phase (old schema removed).
npm run devYou'll see users and teams tables, empty but with the correct columns. Add a test user:
psql $(xata branch url) -c "INSERT INTO users (email, name) VALUES ('test@example.com', 'Test User');".
├── .claude/skills/ # Claude Code slash command skills
├── migrations/ # pgroll migration files (YAML)
│ ├── 001_create_users.yaml
│ ├── 002_add_role.yaml
│ └── 003_add_teams.yaml
├── src/
│ ├── app/ # Next.js app router
│ └── lib/ # Database connection (postgres driver)
├── .env.example
└── package.json
| Command | What it does |
|---|---|
xata auth login |
Authenticate with Xata |
xata init |
Link project to current folder |
xata branch create --name <name> |
Create an isolated database branch |
xata branch wait-ready <name> |
Wait for a branch to be ready |
xata branch url [branch] |
Get connection string |
xata roll init |
One-time pgroll setup |
xata roll start <file> |
Begin expand phase (both schemas live) |
xata roll complete |
Contract phase (old schema removed) |
xata roll status |
Check migration progress |
xata roll rollback |
Undo expand phase if needed |
xata clone start --source-url <url> |
Clone with PII anonymization |
Built on the shoulders of:
- pgroll — Apache 2.0, zero-downtime Postgres migrations
- pgstream — Apache 2.0, Postgres replication and anonymization
- Claude Code — agentic CLI workflows
- Next.js — the React framework
