supabase start runs the stack locally; diff, push and gen types there

Pin the CLI per project, commit config.toml, keep structure in migrations and data in seed.sql, and regenerate TypeScript types after every schema change.

Getting Started

· Chapter

10

·

3

min read

The answer. The CLI (npm i -D supabase, then npx supabase …, pinned per project so teammates and CI agree on a version) runs the entire platform in Docker. supabase init writes supabase/config.toml, which you commit; supabase start boots Postgres, Auth, PostgREST, Storage, Realtime, Studio and a mail catcher, and prints the local keys. Two files carry your state between machines: migration files under supabase/migrations/ (structure, generated from a running database with db diff -f name or hand-written with migration new) and supabase/seed.sql (data, which runs only on a fresh database or db reset). Types come from the schema (gen types typescript), so regenerate them in the same commit as the migration.

The pattern.

npx supabase start                      # API 54321 · Postgres 54322 · Studio 54323 · mail catcher 54324
npx supabase migration new add_tickets  # hand-written SQL, or:
npx supabase db diff -f add_tickets     # capture what you changed in Studio
npx supabase db reset                   # replay migrations + seed.sql from scratch
npx supabase gen types typescript --local > packages/db/types.ts
npx supabase link --project-ref <ref> && npx supabase db push --dry-run   # what would apply remotely

Watch out.

  • db push applies migrations by comparing file names against the remote's list, not by diffing schemas. A file edited after it was applied is silently skipped; a table created by hand on the server is never noticed.
  • db reset also turns Realtime off on every table and drops UI-only settings; capture those in migrations too.
  • Extensions installed in pg_catalog (pg_cron) are missed by db diff; write that create extension line yourself.

Related: tracked-migration-ledger-checksum-same-transaction · branching-gives-each-pr-a-database-without-your-data · first-table-enable-rls-write-one-policy-query-it