Skip to content

Supabase (Local)

Run a full Supabase stack on your machine with the official Supabase CLI. supabase start spins up Postgres, Auth (GoTrue), Studio, and Storage in Docker so App-name can develop and test against a real database without touching the hosted projects. For the hosted projects (production and test) and OAuth setup, see Supabase (Hosted).

Looking for the full workflow?

This page is the Supabase stack reference — install, start, ports, env. For the end-to-end local-first loop (populate by cloning the hosted test data, seed login users, and bring schema changes back upstream) see Local Development.

Who owns which schema

The local stack owns the auth and storage schemas. Alembic owns the public app tables — they are built from your migrations, never by hand in Studio.

Install the CLI

The CLI is distributed through package managers (it is not installed globally via npm). Docker must be running — see Docker (macOS) to install and configure Docker Desktop.

# macOS / Linux (Homebrew)
brew install supabase/tap/supabase

# Verify
supabase --version

Initialize the project

Run once at the repo root. This creates a supabase/ directory holding config.toml, migrations, and seed files.

supabase init

Start the stack

supabase start

The first run pulls the Docker images and may take a minute. When it finishes, the CLI prints the local URLs and keys:

Service URL Port
API gateway (Kong) http://localhost:54321 54321
Postgres database postgresql://postgres:postgres@localhost:54322/postgres 54322
Studio (dashboard) http://localhost:54323 54323

The same output includes a local anon key and service_role key. These are deterministic local development keys (the same on every machine) — they are not secret and never reach production.

You can reprint the URLs and keys at any time:

supabase status

Wire up local env vars

Point your local .env at the local stack, copying the anon key from supabase status:

# .env (local development)
VITE_SUPABASE_URL=http://localhost:54321
VITE_SUPABASE_ANON_KEY=<local anon key from `supabase status`>
SUPABASE_SERVICE_KEY=<local service_role key from `supabase status`>

# App database connection (used by Alembic and the API)
DATABASE_URL=postgresql://postgres:postgres@localhost:54322/postgres

Keep local auth minimal

For day-to-day development, use email/password only. Local Supabase enables it out of the box and it needs no external setup. Configuring a TOTP authenticator or social login locally adds friction with little payoff.

OAuth needs the hosted project

Google and Microsoft OAuth redirect through the provider back to a registered Supabase callback URL, which is awkward to satisfy against localhost. Test the real OAuth flows against the hosted test project instead — see Supabase (Hosted).

Run migrations and seed

Apply Alembic migrations against the local database using the DATABASE_URL above. The migration commands and workflow are documented in Migrations.

# Apply Alembic migrations to local Postgres
cd backend && alembic upgrade head

Seed data on startup by placing SQL in supabase/seed.sql; it runs automatically on supabase start and whenever you reset:

# Drop, recreate, re-apply migrations, and re-seed the local DB
supabase db reset

Stop the stack

# Stop the containers (data is preserved)
supabase stop

# Stop and wipe local data
supabase stop --no-backup

How local relates to the hosted projects

flowchart LR
    Dev[Local dev<br/>supabase start] -->|same schema| Test[Hosted test<br/>test.your-domain]
    Test -->|promote| Prod[Hosted production<br/>your-domain]

Local is for fast iteration and running migrations before they reach a shared environment. The test and production hosted projects are the deployed targets. Keep schema changes flowing one direction — author and verify migrations locally, then apply the same migrations to test and production. To populate local with realistic data, clone the hosted test database down; see Dump & Load for the procedure and Local Development for the full populate-and-bring-back workflow.