# Local development with the Supabase CLI

> Run the full Supabase stack on your machine with the Supabase CLI and develop against it, then ship to SupaHost. Which CLI commands work, which don't, and how to set up a project.

Source: https://supahost.app/docs/local-development/overview · Updated 2026-11-11

The Supabase CLI runs a complete Supabase stack in Docker on your machine: Postgres, Auth, the Data API, Storage, Realtime, Edge Functions and Studio. Developing against it is fast, free and safe, and everything you build there runs on SupaHost because SupaHost runs the same open-source stack.

What doesn't carry over is the CLI's connection to the hosted platform. Commands such as `supabase link`, `supabase db push` to a linked project and `supabase functions deploy` talk to Supabase's Management API, which SupaHost doesn't provide. You develop locally with the CLI, then ship to SupaHost through the MCP server, Studio or (on Business) the SSH tunnel.

## What works and what doesn't

| Command | With SupaHost |
|---|---|
| `supabase init`, `start`, `stop`, `status` | Works (local) |
| `supabase migration new`, `migration list` (local) | Works |
| `supabase db diff`, `db reset`, `db lint` | Works (local) |
| `supabase gen types` against the local database | Works |
| `supabase test db` | Works (local) |
| `supabase functions new`, `functions serve` | Works (local) |
| `supabase link` | Doesn't work |
| `supabase db push` / `db pull` to a linked project | Doesn't work |
| `supabase functions deploy`, `secrets set`, `config push` | Doesn't work |
| `supabase gen types` with a project ref | Doesn't work |

On Business and Enterprise, database commands that accept a Postgres URL can reach your project through the SSH tunnel; see [Migrations workflow](/docs/local-development/migrations-workflow). For the full list, see [Supabase CLI commands that don't work with SupaHost](/kb/cli-forbidden-or-unsupported).

## Install the CLI and Docker

You need Docker Desktop (or another Docker-compatible runtime) running. Then install the CLI, for example as a dev dependency so everyone on the project uses the same version:

```bash
npm install supabase --save-dev
npx supabase --version
```

It's also available through Homebrew (`brew install supabase/tap/supabase`) and Scoop on Windows.

The CLI is at version 3. Version 3 runs database commands against the local stack by default; version 2 needed `--local` on some of them. The commands on this page work on both unless noted.

## Set up a project

In your app's repository:

```bash
npx supabase init
```

This creates a `supabase/` folder with `config.toml`, a `migrations/` folder and a place for functions and seed data. Commit it.

SupaHost runs Postgres 17, so make sure the local database matches:

```toml
# supabase/config.toml
[db]
major_version = 17
```

Start the stack:

```bash
npx supabase start
```

The first start downloads the images and takes a few minutes. When it's done, the CLI prints your local URLs and keys:

| Service | Default local address |
|---|---|
| API (Auth, REST, Storage, Functions) | `http://127.0.0.1:54321` |
| Postgres | `postgresql://postgres:postgres@127.0.0.1:54322/postgres` |
| Studio | `http://127.0.0.1:54323` |
| Email testing inbox | `http://127.0.0.1:54324` |

Run `npx supabase status` any time to see them again, and `npx supabase stop` when you're done.

## Point your app at the local stack

Use one set of environment variables for local work and another for SupaHost. For a Next.js app:

```bash
# .env.development.local
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon key printed by supabase start>
```

```bash
# Production env vars on your host
NEXT_PUBLIC_SUPABASE_URL=https://app-one.acme.supahost.space
NEXT_PUBLIC_SUPABASE_ANON_KEY=<anon key from the Connect tab>
```

Your code doesn't change between the two. Sign-up emails sent locally land in the email testing inbox instead of a real mailbox.

## Develop the schema locally

Create a migration, write SQL, and apply it to your local database:

```bash
npx supabase migration new create_bookings
```

```sql
-- supabase/migrations/20261111093000_create_bookings.sql
create table public.bookings (
  id bigint generated always as identity primary key,
  guest_id uuid not null references auth.users (id) default auth.uid(),
  room text not null,
  starts_at timestamptz not null,
  nights int not null check (nights > 0)
);

alter table public.bookings enable row level security;

create policy "Guests see their own bookings"
  on public.bookings for select
  to authenticated
  using ((select auth.uid()) = guest_id);
```

```bash
npx supabase db reset   # rebuilds the local DB from all migrations and the seed file
```

Prefer clicking in local Studio? Make the change there, then capture it as a migration file:

```bash
npx supabase db diff -f add_room_index
```

## Generate types

```bash
npx supabase gen types typescript > src/database.types.ts
```

On CLI version 2, add `--local`. You can also generate types from a SupaHost project with the MCP tool `generate_typescript_types`. See [Generating TypeScript types](/docs/api/generating-types).

## Edge Functions locally

`supabase functions new` and `supabase functions serve` run functions on your machine against the local stack. To put a function on SupaHost, deploy it from the project's **Functions** tab (paste the files into the editor and click **Deploy function**) or ask an AI agent to deploy it over MCP. Keep the entry file named `index.ts`. See [Deploying functions](/docs/functions/deploying).

## Settings that live outside migrations

`config.toml` controls local Auth settings, but the CLI can't push it to SupaHost. Set the real values on your project's **Auth** tab: Site URL, Redirect URLs, providers and sign-in options. Function secrets go on the **Functions** tab.

## Next steps

- [Migrations workflow: local to SupaHost](/docs/local-development/migrations-workflow)
- [Seeding data](/docs/local-development/seeding)
- [Testing your database](/docs/local-development/testing)
- [supabase functions deploy doesn't work with SupaHost](/kb/cli-functions-deploy)
