Repository navigation
Supabase CLI v3.0.0 — 2026-11-02
v3 is a major release. Commands that can run locally now target your local stack by default, one --remote flag replaces --linked, --project-ref and --db-url, and every change to a hosted project asks for confirmation (or --yes in CI). Flags and SUPABASE_* environment variables now override config.toml, and deprecated commands, flags, config keys and the bundled supabase-go binary are gone. Read the breaking changes before you upgrade CI.
The v2 to v3 migration guide walks through each change.
Try the experimental local stack. Each project, worktree or agent gets its own local Supabase that starts in seconds, on Docker or Podman, or with no container engine at all through
supabase start --runtime native. Start a new project withSUPABASE_EXPERIMENTAL_STACK=1 supabase init; for an existing one, follow the setup steps in the blog post. The multiple local projects guide covers listing, stopping and removing projects. It's experimental, so its flags and output can still change.
⚠️ Breaking changes
Local by default, one --remote flag
db push,db pull,db dump,migration fetch/list/repair,inspect db *,inspect report,gen typesandstorage ls/cp/mv/rmtarget the local stack when you pass no target. Add--remotefor the linked project,--remote=<ref>for another project,--remote=<branch>for a branch of the linked project, or--remote=<postgres-url>for a database URL.SUPABASE_PROJECT_IDon its own no longer selects a hosted project; it only says which project bare--remotemeans. (#7188)--linked,--project-ref,--db-urlandgen types --project-idare deprecated. They still work, print a warning naming the--remoteform, and are hidden from help.--localdoes nothing and warns. None of them can be combined with--remote=<value>. (#7188)gen typeswith no target generates from the local database instead of opening a project picker.db schema declarative syncwith no declarative files generates them from the local database; runsupabase db schema declarative generate --remotefirst to start from the linked project. (#7188)--remote <word>after a command that takes an operand fails with a "did you mean" error when the word looks like a branch name or project ref. Put the operand first (supabase db pull add_profiles --remote) or use--remote=<branch>. (#7188)db diffrejects--remotetogether with--from/--to(use--from=remoteor--to=remote),db queryrejects SQL passed both as an argument and with--file, and an empty--project-ref=is now an error. Bare--remotein an unlinked checkout opens the project picker in an interactive terminal. (#7188)
Every hosted change needs your consent
- Every command that changes a hosted project asks first, and fails unattended unless you pass
--yes. Non-interactive, JSON, stream-json, agent and-o json|yaml|toml|envruns fail withHostedMutationConsentRequiredError. This includesdb push,db pullwhen it updates the remote migration history,pull(except--dry-run),functions deploy/delete,secrets set/unset,config push,brancheschanges,backups restore, project and org create/delete, and the project settings commands.migration up/down/squash/repair,db reset,test db,db query,seed bucketsandstorage cp/mv/rmneed it against a hosted target;db query --read-onlydoesn't. The migration guide has the full list. (#7188) - The default answer is No. Pressing Enter now declines
db push, deploys, secrets changes and migration history updates. Onlyprojects,branches,orgsanddomains create, andbootstrap, default to Yes. (#7188) - A
ypiped on stdin no longer confirms, andSUPABASE_YESin a.envfile no longer counts. When an env file in the working directory definesSUPABASE_YES, a shell-exported one doesn't count either. Use--yes. (#7188) secrets unsetdefaults to No and needs--allto remove every secret. Running it with no secret names now fails. (#7172)- Declining fails with
HostedMutationDeclinedError, replacing the per-command cancelled error codes. Decliningdb pullorpullwrites no files. (#7188) db push, hosteddb reset,config pushandfunctions deploy --pruneask one combined question, and--prunenow runs even when every function is up to date. Removing network bans automatically while connecting now needs--yes.migration downandmigration repair --allon the local database no longer prompt. (#7188)- Commands that resolve a target print
Target: …once on stderr. JSON object results and error envelopes gain atargetobject;db reset'stargetchanges from a string to that object, andconfig pushJSON dropsdeclined_addonsand its skipped status. (#7188)
Flags and env vars override config
- Every value now resolves as flag > shell environment > project env files >
config.json/config.toml> default, and that includes a matched[remotes.<name>]block. Project env files are.env.<SUPABASE_ENV>.local,.env.local,.env.<SUPABASE_ENV>and.env, insupabase/and then the project root.SUPABASE_ENVdefaults todevelopment. (#7074) - If you deploy with
[remotes.*]blocks, audit theSUPABASE_*variables in CI and in your env files. They now beat the block, andconfig pushpushes them (labelled per value;config diffshows the same). SetSUPABASE_ENVin CI so.env.developmentdoesn't apply. (#7074) - Without a
project_idinconfig.toml, local containers and volumes are named after the project folder, not the project ref. Runsupabase stopbefore upgrading, or setproject_id. (#7074) - An invalid config value or
SUPABASE_*variable (for exampleSUPABASE_STUDIO_PORT=abc) now fails every command that loads config withCliConfigValueError. Boolean variables accept only1/t/trueand0/f/false(withT,True,TRUE,F,False,FALSE). (#7074) - Seeding a project matched by a
[remotes.*]block asks first unless the block setsdb.seed.enabled = true.SUPABASE_DB_PASSWORDis no longer sent to a project other than the linked one, and--passwordwith a local or URL target exits 1. (#7074) - Without
--workdir, the nearest directory withsupabase/config.tomlorsupabase/config.jsonwins.supabase link --passwordis ignored, ports with a leading zero are rejected, andMigrationPasswordFlagsErroris nowDbPasswordFlagsError. (#7074)
Removed commands, flags and config
Each removed command or flag exits 1 and prints its replacement. (#6609, #7109, #7116, #7176)
| Removed | Use instead |
|---|---|
db remote commit |
db pull |
db remote changes |
db diff --remote |
db branch create/delete/list/switch |
branches for hosted preview branches |
gen keys |
projects api-keys |
inspect db total-index-size |
inspect db index-stats |
inspect db total-table-sizes, table-index-sizes |
inspect db table-stats |
db diff --use-pg-schema |
the default engine, or --use-pg-delta |
db pull --use-pg-delta, db pull --experimental |
db pull --declarative |
functions download --legacy-bundle |
functions download --use-api |
--include-raw-output on domains commands |
-o json |
--create-ticket |
supabase issue bug |
supabase-go binary |
supabase |
[inbucket], INBUCKET_URL, inbucket.url |
[local_smtp], MAILPIT_URL, mailpit.url |
[experimental] orioledb_version |
[db] orioledb_version |
SUPABASE_EXPERIMENTAL_ORIOLEDB_VERSION |
SUPABASE_DB_ORIOLEDB_VERSION |
linkedin and slack auth providers |
linkedin_oidc and slack_oidc |
import_map.json inside a function directory |
deno.json, or functions.<slug>.import_map |
COBRA_COMPLETION_DESCRIPTIONS |
SUPABASE_COMPLETION_DESCRIPTIONS |
Other behavior changes
[auth.sms] enable_confirmations = false, theinitdefault, now turns phone confirmation off onconfig push. Set it totrueto keep phone codes, and runconfig diffbefore pushing. (#7221)db advisors --remoteno longer connects to the database first, so it no longer resolves database settings, creates a temporary login role or removes network bans. (#7297)- Error messages that quoted Go library errors are reworded, for example
expected a booleaninstead ofstrconv.ParseBool: …. Update anything that matches on error text. (#7064)
Highlights
db resetstops failing at random — the intermittenterror running container: exit 1at "Initialising schema…", mostly seen in CI, is gone. (#7380)linkworks with least-privilege tokens — a project-scoped token that can't read secret API keys can now link anddb push; the CLI warns and skips the optional version checks instead of failing. (#7388)[auth.email] enabledand[auth.sms] enabled—enable_signupin those sections switched the whole provider off, blocking existing users from signing in, not just new signups. Useenabledfor the provider toggle and[auth] enable_signupto stop new signups; the old keys still work but are deprecated. (#7398)
New features
- Plan-gate details in JSON errors — when your plan doesn't include a feature,
--output-format jsonandstream-jsonerrors carry anentitlementobject withfeatureandupgrade_url, so scripts and agents don't have to parse the message. (#7271)
Improvements
- Better editor support for
config.toml: the published config schemas use draft-07, which Taplo (Even Better TOML) understands, acceptenv()on number, boolean, enum and list fields, and mark secret fields withx-secret. (#7330, #7333, #7366) - With
SUPABASE_USE_SLIM_IMAGES, a GHCR rate limit no longer failssupabase start; the CLI pulls the same image from ECR Public instead. (#7350) supabase initadds a commented[auth.web3.ethereum]example toconfig.toml. (#7334)- Experimental stack: the gateway serves
/graphql/v1(so Studio's GraphiQL works),/rest-admin/v1,/pg/,/analytics/v1/and/pooler/v2/, forwardsX-Forwarded-ForandX-Real-IPto upstreams, and Edge Functions that boot together no longer fail with503 BOOT_ERROR. (#7345, #7347, #7382)
Bug fixes
supabase startandsupabase db startrecover from a database container left in Docker'screatedstate, instead of failing withcontainer is not running: created. (#7369)- Overlapping
startandstopruns on the same project no longer fail withnetwork supabase_network_<id> not found. (#7372) supabase startworks on nested or sandboxed Docker hosts wheredocker execfails, instead of timing out on health checks. (#7362)secrets sethonors--workdirandSUPABASE_WORKDIRinstead of uploading secrets from the current directory. (#7361)- Local
db advisorslints every schema exposed in[api], instead of onlypublicor sometimes nothing. (#7379) db pushanddb resetplace the migration error caret correctly when accented letters or emoji come before the failing token. (#7351)config pushno longer fails when you change the OAuth server path or turn the OAuth server on or off. (#7367)- Restoring a
db dump --role-onlyfile aspostgresno longer fails on a parameter grant to a reserved role. (#7320)
Plus 106 internal improvements and dependency updates.
Full changelog: v2.122.0...v3.0.0