database · side by side
Neon vs Supabase for a Next.js app
Both fill the database slot, so a generated repo carries one or the other, never both. Every line below is read out of the two manifests.
Short answer
Pick Neon if
Teams that want plain Postgres plus a throwaway database per pull request, running on Vercel or another serverless host where connections are scarce.
Pick Supabase if
Teams that want one Postgres provider to also cover auth, storage and realtime. Also teams who want to run the real stack locally, not against a shared dev database.
Supabase is tested with Supabase Auth and Supabase Storage. Neon isn't yet.
Side by side
Price, obligations, and the surface each one adds. No row is written by hand. This is manifest.yaml, rendered.
| From the manifest | Option ANeon | Option BSupabase |
|---|---|---|
| In one line | Neon Serverless Postgres you can branch like git, with a driver built for cold starts. | Supabase Managed Postgres with row level security, realtime and a local stack in Docker. |
| Pricing | Neon Free plan: up to 100 projects, each with 100 CU-hours a month and 0.5 GB of storage. Launch and Scale have no monthly minimum: you pay per CU-hour ($0.106 on Launch) plus $0.35 per GB-month of storage. | Supabase Free: 2 active projects, 500 MB database each, paused after a week idle. Pro is $25/month per organisation with $10 of compute credit, 8 GB disk per project, 7 days of daily backups and no pausing. Extra projects add compute cost. |
| Best for | Neon Teams that want plain Postgres plus a throwaway database per pull request, running on Vercel or another serverless host where connections are scarce. | Supabase Teams that want one Postgres provider to also cover auth, storage and realtime. Also teams who want to run the real stack locally, not against a shared dev database. |
| Trade-offsVerbatim from the manifest | Neon
| Supabase
|
| Required companionsAdded for you, with a reason | Neon
| Supabase
|
| Recommended alongsideSuggested, never added for you | Neon Nothing suggested. | Supabase
|
| Env vars you will manageEvery one documented in docs/onboard.md | Neon 4 variables · 1 required
| Supabase 6 variables · 3 required
|
| Dependencies added | Neon
| Supabase
|
| MCP serversWritten into .mcp.json | Neon
| Supabase
|
| Footprint in your repo | Neon 5 files, plus 5 injections into shared stack files | Supabase 8 files, plus 4 injections into shared stack files |
What changes in your repo
The paths each battery contributes, diffed. A path in the third list is written by both, so swapping rewrites that file rather than adding one.
Only with Neon (4)
scripts/2 files
- db-branch.ts
- neon-local-proxy.ts
src/2 files
db/2 files
- health.ts
- neon-local.ts
Only with Supabase (7)
src/1 file
db/1 file
- url.ts
supabase/2 files
seed/1 file
- 00_conventions.sql
- config.toml
variants/4 files
browser-anon/1 file
src/1 file
db/1 file
- supabase-browser.ts
browser-shared-session/1 file
src/1 file
db/1 file
- supabase-browser.ts
starter-profiles/2 files
supabase/2 files
migrations/1 file
- 20250101000000_init_profiles.sql
seed/1 file
- 10_profiles.sql
Same path, different implementation (1)
src/1 file
db/1 file
- client.ts
Shared stack files Neon injects into
- db-client
- env-required
- hook-probes
- legal-processors
- verify-checks
Shared stack files Supabase injects into
- db-client
- env-required
- legal-processors
- verify-checks
Neon in your .env.local
# required
DATABASE_URL=postgresql://user:password@ep-example-123456-pooler.us-east-2.aws.neon.tech/neondb?sslmode=require
# optional
DATABASE_URL_UNPOOLED=postgresql://user:password@ep-example-123456.us-east-2.aws.neon.tech/neondb?sslmode=require
NEON_API_KEY=neon_api_key_xxxxxxxxxxxxxxxxxxxx
NEON_LOCAL_PROXY=
Supabase in your .env.local
# required
DATABASE_URL=postgresql://postgres.<project-ref>:<password>@aws-0-<region>.pooler.supabase.com:6543/postgres
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example.anon-key
NEXT_PUBLIC_SUPABASE_URL=https://<project-ref>.supabase.co
# optional
DIRECT_URL=postgresql://postgres.<project-ref>:<password>@aws-0-<region>.pooler.supabase.com:5432/postgres
SUPABASE_ACCESS_TOKEN=sbp_0000000000000000000000000000000000000000
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example.service-role-key
What changes for your agents
Each battery ships rules, skills, subagents and hooks that an agent loads before it touches the code that battery owns. Picking one is also picking how your agents behave in src/db/**.
Neon
1
Agents
2
Skills
2
Rules
1
Hooks
6
Solution docs
1
MCP servers
Rules (2)
One connection surface, and the right driver for the job
src/db/** · src/app/api/**
Schema changes go through ORM migration files on the direct URL
src/db/**
Skills (2)
/db-branch
Create, use, reset and delete Neon database branches, for a feature branch, a preview deploy, a migration rehearsal or a point-in-time investigation.
/migrate-on-neon
Run a schema migration against Neon safely, on the direct URL, rehearsed on a branch first, with a recovery path when it fails halfway.
Subagents and hooks
db-inspector
Read-only Neon Postgres inspector. Explains schema, data shape and query plans. Runs SELECT and EXPLAIN only, and refuses every statement that writes or changes schema.
guard-neon-sql
Blocks raw DDL through psql, migrations that would really run through the Neon pooler, and schema pushes that skip migration files. The repo's own db:migrate scripts pass.
PreToolUse · Bash
Supabase
2
Skills
2
Rules
5
Solution docs
1
MCP servers
Rules (2)
Row level security is on by default and the service role is a last resort
src/db/**
Schema changes go through supabase/migrations, never the dashboard
supabase/**
Skills (2)
/add-rls-policy
Add or fix row level security policies on a Supabase table, with a migration, a policy test and regenerated types.
/local-supabase
Boot, reset, inspect and troubleshoot the local Supabase stack, and pull schema down from a hosted project.
Subagents and hooks
None of its own. The foundation agents and guard hooks still ship.
What each one already knows
Solution docs land in docs/solutions/ in your repo and are published here, so you can read the failure modes before you commit.
Neon (6)
- A Neon branch per preview deploymentPreview deploys that share the production database corrupt it or lie to you. Give every preview its own copy-on-write Neon branch, wired to the deployment's environment variables.docs/solutions/neon/branch-per-preview-deployment.md
- Neon cold starts, where the half second goes and what to do about itScale-to-zero means an idle branch takes roughly 500 ms to wake, and a serverless function adds its own cold start on top. How to measure the parts and fix the ones that matter.docs/solutions/neon/cold-start-latency.md
- Connection exhaustion on serverless Postgres, and how to actually fix itServerless does not queue requests on a pool, it creates pools. Here is the arithmetic, the four real causes, and the fix for each.docs/solutions/neon/connection-exhaustion-in-serverless.md
- Local Postgres with the Neon serverless driver, no Neon accountThe Neon driver speaks HTTPS and WebSocket, not the Postgres wire protocol. A small local proxy plus two neonConfig settings let it run against a Postgres on your laptop, with no code fork.docs/solutions/neon/local-postgres-without-a-neon-account.md
- Running migrations on Vercel without a half-applied schemaVercel has no migration step, so people add one in the wrong place. Where migrations belong in the build, why the direct URL is mandatory, and how to deploy a breaking change in two safe halves.docs/solutions/neon/migrations-on-vercel.md
- Neon's pooled and unpooled connection strings, and which one to use whereThe -pooler host and the direct host are not interchangeable. Runtime queries need the pooler; migrations, advisory locks and session state need the direct endpoint.docs/solutions/neon/pooled-vs-unpooled-connections.md
Supabase (5)
- Server code should stop using the anon key, and must not reach for the service role insteadThe anon key is a public identifier, not a credential. Server work needs either the caller's JWT or a deliberate, audited service-role call. Here is how to tell which.docs/solutions/supabase/beyond-the-anon-key-on-the-server.md
- Supabase gives you three connection strings: pick the right one or production falls overDirect on 5432, session pooler on 5432, transaction pooler on 6543. Which one serverless needs, why prepared statements break, and what to run migrations on.docs/solutions/supabase/direct-vs-pooler-connection-strings.md
- Stopping Supabase generated types from drifting out of the schemaGenerated database types are only true at the moment they were generated. Commit them, regenerate them in the same commit as the migration, and check them in verify.docs/solutions/supabase/generated-types-drift.md
- Local Supabase or a hosted branch - pick per environment, not per teamThe CLI stack and Supabase branching solve different problems. Use local for the inner loop, a branch for preview deploys, and never share one dev project.docs/solutions/supabase/local-dev-vs-supabase-branches.md
- Row level security when an ORM is doing the queryingYour ORM connects as the postgres superuser, so RLS never runs. Here is how to keep policies meaningful without giving up typed queries.docs/solutions/supabase/rls-with-an-orm-in-front.md
Which one to pick
From meta.bestFor and meta.tradeoffs. If a claim is not in the manifest, it is not on this page.
Pick Neon when
Teams that want plain Postgres plus a throwaway database per pull request, running on Vercel or another serverless host where connections are scarce.
And accept that(5)
- Standard Postgres. ORMs and psql work unchanged, with no custom query layer to learn.
- Branching is copy-on-write, so a preview branch of a 20 GB database only adds storage for what the branch changes.
- Compute scales to zero after 5 idle minutes and wakes in a few hundred milliseconds. On low-traffic previews that shows up as a slow first request.
- Database only. No auth, storage, realtime or generated API. Pair it with Better Auth or Clerk. Supabase bundles those.
- Two connection strings to keep straight (pooled and direct). Point a migration at the pooled one and it fails in confusing ways.
Pick Supabase when
Teams that want one Postgres provider to also cover auth, storage and realtime. Also teams who want to run the real stack locally, not against a shared dev database.
And accept that(6)
- A full Postgres, not a subset: extensions, triggers, functions and logical replication all work.
- Row level security is the security model. Going through the service role key everywhere throws away most of what you are paying for.
- The local CLI boots Postgres, PostgREST, GoTrue, Realtime and Storage in Docker, so the dev loop needs Docker running.
- Branching exists but is a paid feature and slower to spin up than a local reset. Most teams use local for the inner loop and branches for previews.
- Two connection strings: direct on port 5432 and the pooler on 6543. Pick the wrong one for a serverless runtime and you run out of connections in production.
- Auth, storage and realtime are optional. Using Supabase purely as Postgres is supported and common.
Questions people actually ask
- Should I choose Neon or Supabase?
- Neon is best for teams that want plain Postgres plus a throwaway database per pull request, running on Vercel or another serverless host where connections are scarce. Supabase is best for teams that want one Postgres provider to also cover auth, storage and realtime. Also teams who want to run the real stack locally, not against a shared dev database. Both fill the database slot, so a generated repo carries one or the other, never both.
- How much do Neon and Supabase cost?
- Neon: Free plan: up to 100 projects, each with 100 CU-hours a month and 0.5 GB of storage. Launch and Scale have no monthly minimum: you pay per CU-hour ($0.106 on Launch) plus $0.35 per GB-month of storage. Supabase: Free: 2 active projects, 500 MB database each, paused after a week idle. Pro is $25/month per organisation with $10 of compute credit, 8 GB disk per project, 7 days of daily backups and no pausing. Extra projects add compute cost.
- What changes in my repo if I switch from Neon to Supabase?
- Neon writes 5 files, 4 environment variables and 3 dependencies, and installs 2 path-scoped rules, 2 skills and 6 solution docs. Supabase writes 8 files, 6 environment variables and 4 dependencies, and installs 2 path-scoped rules, 2 skills and 5 solution docs.
Decide once, then build the repo that already knows the decision.
Either way you get that choice’s rules, skills and solution docs installed, plus the guard hooks, an onboarding doc for exactly these env vars, and the Compound Engineering loop. Free and MIT.