Skip to content
Documentation GitHub
Development Guides

Set Up Supabase Locally

Guide for running a local Supabase instance for development on auth, sync, or cloud features.

Goal

Start a local Supabase stack (Postgres, Auth, Storage, Studio) so you can develop and test cloud-dependent features without connecting to the staging or production Supabase project.

Prerequisites

  • Docker Desktop installed and running (docker info should succeed)

  • Supabase CLI installed:

    Terminal window
    brew install supabase/tap/supabase

    Verify with supabase --version.

  • The project cloned and dependencies installed (pnpm install)

Steps

1. Start the local Supabase stack

From the project root:

Terminal window
supabase start

This reads supabase/config.toml and starts Docker containers for Postgres, Auth (GoTrue), Storage, Studio, and other services. The first run downloads container images and may take several minutes.

On success, the CLI prints a status table with connection details:

API URL: http://127.0.0.1:54321
GraphQL URL: http://127.0.0.1:54321/graphql/v1
S3 Storage URL: http://127.0.0.1:54321/storage/v1/s3
DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
Studio URL: http://127.0.0.1:54323
anon key: eyJ...
service_role key: eyJ...

Note the API URL and anon key values — you will need them in the next step.

2. Configure environment variables

Copy the example file if you have not already:

Terminal window
cp .env.example .env

The .env file is gitignored. Set the two Supabase variables to point at your local instance:

SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_PUBLISHABLE_KEY=<anon key from supabase start output>

The Rust backend loads .env via dotenvy at startup (apps/desktop/src-tauri/src/main.rs). The SupabaseConfig struct resolves SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY from runtime environment variables first, falling back to compile-time values only for release builds. See crates/infrastructure/supabase/src/config.rs for the resolution logic.

You can retrieve these values again at any time:

Terminal window
supabase status

3. Verify the setup

Open the Supabase Studio dashboard in your browser:

http://127.0.0.1:54323

Studio provides a web UI for browsing tables, running SQL, inspecting auth users, and managing storage buckets. Confirm that you can see the tables defined in the baseline migration (e.g., users, devices, workspaces).

4. Apply and reset migrations

All Supabase (Postgres) migrations live in supabase/migrations/. The local stack applies them automatically on supabase start. The current migration files are:

  • 00000000000000_baseline.sql — flattened baseline covering all cloud sync tables, RLS policies, and functions
  • 20260303000000_create_templates_bucket.sql — templates storage bucket and RLS policy

To reset the local database to a clean state (drops all data, re-applies migrations and seed data):

Terminal window
supabase db reset

This also runs supabase/seed.sql, which creates a test auth user:

FieldValue
Emailtest@example.com
Passwordpassword123
NameTest User

5. Run the desktop app against local Supabase

With the .env configured and supabase start running:

Terminal window
pnpm desktop:dev

In dev mode, the app uses an in-memory auth repository instead of the OS keychain to avoid repeated keychain authorization prompts from unsigned binaries. Auth tokens are still managed identically, but they do not survive app restarts.

6. Stop Supabase

When you are done developing:

Terminal window
supabase stop

This stops all Docker containers but preserves the database volume. Data persists across stop/start cycles. To also remove the database volume and start completely fresh next time:

Terminal window
supabase stop --no-backup

Common Issues

Docker is not running

Error: Cannot connect to the Docker daemon

Start Docker Desktop before running supabase start.

Port conflicts

The local Supabase stack uses these ports (configured in supabase/config.toml):

ServicePort
API54321
Postgres54322
Studio54323

If another process occupies these ports, supabase start will fail. Stop the conflicting process or edit supabase/config.toml to use different ports (note: changing API port requires updating SUPABASE_URL in .env).

Migration errors after pulling new changes

If someone added a new migration upstream, run:

Terminal window
supabase db reset

This drops and recreates the local database with all migrations applied in order.

App fails to start with “Missing required environment variable”

The SupabaseConfig::from_env() call requires both SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY. Verify your .env file exists in the project root and contains non-empty values for both. Run supabase status to confirm the local stack is running and retrieve the correct values.

Configuration Reference

The local Supabase configuration is defined in supabase/config.toml:

  • API (port 54321): REST and GraphQL endpoints
  • DB (port 54322): Direct Postgres access (postgres:postgres credentials)
  • Studio (port 54323): Web dashboard
  • Auth: Email signup enabled, email confirmations disabled for local dev, custom email templates in supabase/templates/
  • MFA: TOTP and WebAuthn enrollment enabled
  • Storage buckets: workspace-attachments (10 MB limit, private) and templates (1 MB limit, JSON only)

See Also

  • Writing a Migration — adding workspace SQLite migrations (separate from Supabase Postgres migrations)
  • Auth Flow — how authentication flows through the system
  • Sync Flow — how sync uses Supabase for cloud storage
  • supabase/config.toml — local Supabase configuration
  • supabase/seed.sql — seed data for local development
  • crates/infrastructure/supabase/src/config.rs — environment variable resolution logic

Was this page helpful?