Claude Code for Neon Branching — Workflow Guide

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

The Setup

You are using Neon’s serverless Postgres with its branch-based workflow for database development. Neon lets you create instant copy-on-write database branches — like Git branches but for your data. Claude Code can generate migrations, manage branch lifecycles, and write queries, but it needs to understand that Neon branches are not separate databases and that connection strings change per branch.

What Claude Code Gets Wrong By Default

  1. Hardcodes the main branch connection string. Claude embeds the production connection URL directly. With Neon branching, each branch has its own connection string. The DATABASE_URL must be configurable per environment.

  2. Creates separate databases instead of branches. When asked to set up a dev environment, Claude runs CREATE DATABASE commands. Neon branches are created through the Neon API or CLI, not SQL statements.

  3. Ignores the pooled vs direct connection distinction. Neon provides two endpoints per branch: a pooled connection (for serverless) and a direct connection (for migrations). Claude uses the same URL for both, which causes migration locks on the pooled endpoint.

  4. Writes migrations without considering branch isolation. Claude generates destructive migrations (DROP COLUMN) without considering that the branch workflow lets you test these safely before merging to main.

The CLAUDE.md Configuration

# Neon Serverless Postgres Project

## Architecture
- Database: Neon Serverless Postgres
- ORM: Drizzle ORM (drizzle-orm + drizzle-kit)
- Branching: Neon branches for dev/preview, main branch for production
- Connection: Use pooled endpoint for app, direct endpoint for migrations

## Neon Rules
- DATABASE_URL is the pooled connection (for application queries)
- DIRECT_URL is the unpooled connection (for drizzle-kit migrations only)
- Create branches via `neon branches create --name feat-xyz`
- Never run destructive migrations on the main branch directly
- Branch from main, test migration, then merge via PR
- Connection string format: postgresql://user:[email protected]/dbname
- Add ?sslmode=require to all connection strings

## Conventions
- Migration files in drizzle/migrations/ directory
- One migration per feature branch
- Branch names match git branch names
- Delete Neon branches when PR is merged
- Never use CREATE DATABASE — use Neon CLI for branches

Workflow Example

You want to add a new teams table and test the migration safely. Prompt Claude Code:

“Create a Neon branch for the teams feature, write a Drizzle schema for a teams table with name, plan, and createdAt fields, then generate the migration file.”

Claude Code should output the Neon CLI command to create the branch, update drizzle/schema.ts with the teams table definition, and run drizzle-kit generate to produce the migration SQL file — all pointing at the branch connection string, not production.

Common Pitfalls

  1. Running drizzle-kit push on pooled connections. Claude uses DATABASE_URL for schema pushes. Neon’s pooler does not support the advisory locks that migration tools need. Always use DIRECT_URL for drizzle-kit push and drizzle-kit migrate.

  2. Forgetting to set the branch connection in preview deploys. Claude configures a single DATABASE_URL in .env. Each Vercel preview deployment needs its own Neon branch URL, configured via the Neon Vercel integration or environment variable overrides.

  3. Branch cleanup accumulation. Claude creates branches but never deletes them. Neon has branch limits on free plans. Add neon branches delete to your PR merge workflow or CI cleanup step.