Supabase CLI cheat sheet
Status: 🟩 COMPLETE (🟦 LIVING — Supabase CLI evolves with the platform) Last updated: 2026-06-21 Plain-English tagline: Daily-use Supabase CLI commands grouped by intent. For the why, read Supabase.
Setup (once per machine)
npm install -g supabase # install globally (or use as devDep + npx)
supabase --version # verify
supabase login # interactive browser authPer-project:
supabase init # creates supabase/ folder in your project
supabase link --project-ref <ref> # link to your hosted Supabase projectFind your project ref in the Supabase dashboard URL: app.supabase.com/project/<ref>.
Run Supabase locally (Docker required)
supabase start # spin up local Postgres + Auth + Storage + Studio
supabase stop # tear it down
supabase status # what's running, on which ports
supabase db reset # rebuild local DB from migrations + seedsAfter supabase start:
- Studio:
http://localhost:54323 - API:
http://localhost:54321 - DB:
postgresql://postgres:postgres@localhost:54322/postgres
Migrations
supabase migration new add_users_table # create a new migration file (timestamped)
supabase migration list # list applied + pending migrations
supabase db push # apply pending migrations to the LINKED remote
supabase db pull # generate a migration from remote schema diff
supabase db reset # rebuild LOCAL from scratch (uses all migrations)The Bible Quest project’s migrations live in supabase/migrations/ (e.g. 20260507_001_initial_schema.sql). Naming pattern: YYYYMMDD_NNN_description.sql.
Type generation (TypeScript)
supabase gen types typescript --linked > lib/database.types.ts # types from linked project
supabase gen types typescript --local > lib/database.types.ts # types from local DB
supabase gen types typescript --project-id <ref> > lib/database.types.ts # types from any projectThen in code:
import { Database } from "@/lib/database.types";
const supabase = createClient<Database>(...);
// Now table/column names autocomplete and type-checkRe-run after every migration. Many teams add this to npm run build:types and run it in CI.
Functions (Edge Functions)
supabase functions new my-function # scaffold a function
supabase functions serve # run all functions locally
supabase functions serve my-function --no-verify-jwt # run one, skip auth (dev)
supabase functions deploy my-function # deploy to remote
supabase functions deploy my-function --no-verify-jwt # deploy without JWT enforcement
supabase functions delete my-function # remove from remoteEdge functions live in supabase/functions/<name>/index.ts. Written in Deno-flavored TypeScript.
Secrets (for Edge Functions)
supabase secrets list # what's set
supabase secrets set MY_KEY=value # set one
supabase secrets set --env-file ./.env.functions # bulk-set from file
supabase secrets unset MY_KEY # removeThese are separate from your database env vars — they’re specifically for Edge Functions to access.
Storage
supabase storage cp ./photo.jpg ss:///bucket-name/photo.jpg # upload
supabase storage cp ss:///bucket-name/photo.jpg ./photo.jpg # download
supabase storage ls ss:///bucket-name # list
supabase storage rm ss:///bucket-name/photo.jpg # deleteMost app code uses the SDK (supabase.storage.from("bucket")); the CLI is for quick local file management.
Inspecting the linked project
supabase projects list # all projects in your account
supabase projects api-keys --project-ref <ref> # get URL + anon + service_role keys
supabase db dump --linked # dump remote DB to local file
supabase db dump --linked --data-only # data only, no schemasupabase db dump is great for backups before risky operations.
Common workflows
Start a fresh project locally
supabase init # creates supabase/ folder
supabase start # spin up local stack
# Visit http://localhost:54323 for StudioAdd a new table
supabase migration new add_posts_table
# Edit supabase/migrations/<timestamp>_add_posts_table.sql
# (write your CREATE TABLE statement)
supabase db reset # apply to local
# (test locally)
supabase db push # apply to linked remote
supabase gen types typescript --linked > lib/database.types.ts # refresh typesReset local to match remote
supabase db pull # generate diff migration
supabase db reset # rebuild local from migrationsMove env vars across environments
# (Vercel side)
vercel env pull .env.local # pull production env to .env.local
# (Supabase side — set secrets for Edge Functions)
supabase secrets set --env-file .env.localCommon gotchas
supabase startneeds Docker. Make sure Docker Desktop is running on Windows/macOS.- Ports conflict. Default ports (54321, 54322, 54323) often clash with other dev tools.
supabase statusshows what’s bound;supabase stopcleans up. supabase db pushapplies migrations to the LINKED REMOTE. Triple-checksupabase statusshows the right project before pushing.supabase db resetwipes local data. Local seed data gets reloaded fromsupabase/seed.sql(if present). Remote data is untouched.- Generated types fall out of sync. Re-run
supabase gen typesafter every migration, or types in your app start lying. --no-verify-jwtfor functions disables auth. Useful in dev; never deploy a function with--no-verify-jwtin production unless it’s intentionally public.- GRANTs aren’t generated by
supabase db pull. If you ran raw SQL to grant privileges (the Bible Quest20260507_002_grant_role_privileges.sqlpattern), you may need to re-apply manually. - CLI version drift. If a command behaves unexpectedly:
npm install -g supabase@latest. db pushwon’t apply migrations already in the remote’s migration history. If a migration ran via the SQL Editor manually, the CLI won’t see it as “applied” — you may needsupabase migration repairto sync.- Linked project URL contains the project ref.
https://<ref>.supabase.co— the<ref>is what--project-refexpects.
See also
- Supabase 🟩 🟦 — the textbook
- Postgres 🟩
- Migrations 🟩
- Row-Level Security 🟩
- Schema design 🟩
- Edge functions 🟩
- How-to: Set up a Supabase project 🟩
- Supabase errors 🟩 🟦
- Vercel CLI cheat sheet 🟩 🟦 — for env var sync