Claude Cursor Skill

supabase-cli

This skill should be used when user asks to "use supabase CLI", "supabase init", "supabase start", "run migrations", "deploy edge functions", "manage Supabase project", or works with the supabase command-line tool for local development and project management.

LLM Mart · 0 points · 7 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download fcakyon-claude-codex-settings-plugins_supabase-skills_skills_supabase-cli-4632eb3.zip · 42 KB
Part of fcakyon/claude-codex-settings — 83 skills

Install

skills CLI npx skills add https://github.com/fcakyon/claude-codex-settings/tree/main/plugins/supabase-skills/skills/supabase-cli
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install fcakyon-claude-codex-settings@llmmart
Git git clone https://github.com/fcakyon/claude-codex-settings.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole fcakyon/claude-codex-settings collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Supabase CLI Skill

Skill for local development, migrations, edge functions, and project management with the supabase CLI. Official docs: https://supabase.com/docs/reference/cli/about

Installation

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

# npm
npm install -g supabase

# Windows (Scoop)
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase

Authentication

# Login with access token from https://supabase.com/dashboard/account/tokens
supabase login

# Link to a project
supabase link --project-ref <project-id>

Quick Decision Trees

"I need local development"

Local dev?
├─ Initialize project → supabase init
├─ Start local stack → supabase start
│  ├─ Without specific services → supabase start -x studio,imgproxy
│  └─ Status → supabase status
├─ Stop local stack → supabase stop
│  └─ Clean up data → supabase stop --no-backup
├─ View service URLs → supabase status
└─ Bootstrap from template → supabase bootstrap

"I need database migrations"

Migrations?
├─ Create new migration → supabase migration new <name>
├─ Apply pending migrations → supabase migration up
│  └─ Rollback → supabase migration down
├─ Diff local changes → supabase db diff
│  └─ Save as migration → supabase db diff -f <name>
├─ Pull remote schema → supabase db pull
├─ Push local migrations → supabase db push
├─ Reset local database → supabase db reset
├─ List migrations → supabase migration list
├─ Squash migrations → supabase migration squash
├─ Run arbitrary SQL → supabase db query 'SELECT 1'
├─ Run pgTAP tests → supabase test db
└─ Lint schema → supabase db lint

"I need edge functions"

Edge Functions?
├─ Create new function → supabase functions new <name>
├─ Serve locally → supabase functions serve
│  └─ With env file → supabase functions serve --env-file .env.local
├─ Deploy to project → supabase functions deploy <name>
│  └─ Deploy all → supabase functions deploy
├─ Delete function → supabase functions delete <name>
├─ List functions → supabase functions list
└─ Download function → supabase functions download <name>

"I need to manage secrets"

Secrets?
├─ Set secrets → supabase secrets set KEY=value KEY2=value2
├─ Set from .env file → supabase secrets set --env-file .env
├─ List secrets → supabase secrets list
└─ Unset secrets → supabase secrets unset KEY KEY2

"I need code generation"

Code gen?
├─ TypeScript types from DB → supabase gen types typescript --project-id <id>
│  └─ From local DB → supabase gen types typescript --local
├─ Signing key → supabase gen signing-key
└─ Bearer JWT → supabase gen bearer-jwt --project-ref <ref>

"I need to inspect the database"

Inspect?
├─ Database stats → supabase inspect db db-stats
├─ Slow queries → supabase inspect db outliers
├─ Lock monitoring → supabase inspect db locks / blocking
├─ Long running queries → supabase inspect db long-running-queries
├─ Index analysis → supabase inspect db index-usage / unused-indexes
├─ Table sizes → supabase inspect db table-sizes / table-record-counts
├─ Cache hit ratio → supabase inspect db cache-hit
├─ Bloat → supabase inspect db bloat
├─ Vacuum stats → supabase inspect db vacuum-stats
└─ Replication slots → supabase inspect db replication-slots

"I need project management"

Project management?
├─ Create project → supabase projects create <name> --org-id <id> --db-password <pw> --region <r>
├─ List projects → supabase projects list
├─ Delete project → supabase projects delete --project-ref <ref>
├─ API keys → supabase projects api-keys --project-ref <ref>
├─ Organizations → supabase orgs list / create
├─ Custom domains → supabase domains create / get / activate
├─ Preview branches → supabase branches create / list / delete
├─ Backups (PITR) → supabase backups list / restore
├─ SSO management → supabase sso add / list / remove
└─ Push config → supabase config push

Common Workflows

New project setup

supabase init
supabase start
# Make schema changes in Supabase Studio (http://127.0.0.1:54323)
supabase db diff -f initial_schema
supabase stop

Migration workflow

# Create migration from local changes
supabase db diff -f add_profiles_table

# Or write SQL directly
supabase migration new add_profiles_table
# Edit supabase/migrations/<timestamp>_add_profiles_table.sql

# Test locally
supabase db reset
supabase test db

# Deploy to remote
supabase db push

Edge function development

supabase functions new my-function
# Edit supabase/functions/my-function/index.ts
supabase functions serve  # local dev with hot reload
supabase functions deploy my-function

Generate types after schema change

# From remote project
supabase gen types typescript --project-id <id> > database.types.ts

# From local running instance
supabase gen types typescript --local > database.types.ts

Reference Index

Category Reference Description
Top-level commands references/commands/ init, start, stop, status, login, link
Database references/db/ diff, dump, lint, pull, push, reset, query
Migrations references/migration/ list, new, repair, squash, up, down
Edge Functions references/functions/ new, serve, deploy, delete
Inspect references/inspect/ 20+ database inspection subcommands
Config references/config/ push config to remote
Domains references/domains/ custom domain management
Tests references/test/ pgTAP database tests
Examples references/examples.yaml Usage examples for all commands
Files (claude-codex-settings)
  • references
    • commands
      • functions.md 543 B
        ## supabase-functions
        
        Manage Supabase Edge Functions.
        
        Supabase Edge Functions are server-less functions that run close to your users.
        
        Edge Functions allow you to execute custom server-side code without deploying or scaling a traditional server. They're ideal for handling webhooks, custom API endpoints, data validation, and serving personalized content.
        
        Edge Functions are written in TypeScript and run on Deno compatible edge runtime, which is a secure runtime with no package management needed, fast cold starts, and built-in security.
        
      • gen.md 594 B
        ## supabase-gen
        
        Automatically generates type definitions based on your Postgres database schema.
        
        This command connects to your database (local or remote) and generates typed definitions that match your database tables, views, and stored procedures. By default, it generates TypeScript definitions, but also supports Go and Swift.
        
        Generated types give you type safety and autocompletion when working with your database in code, helping prevent runtime errors and improving developer experience.
        
        The types respect relationships, constraints, and custom types defined in your database schema.
        
      • init.md 471 B
        ## supabase-init
        
        Initialize configurations for Supabase local development.
        
        A `supabase/config.toml` file is created in your current working directory. This configuration is specific to each local project.
        
        > You may override the directory path by specifying the `SUPABASE_WORKDIR` environment variable or `--workdir` flag.
        
        In addition to `config.toml`, the `supabase` directory may also contain other Supabase objects, such as `migrations`, `functions`, `tests`, etc.
        
      • link.md 626 B
        ## supabase-link
        
        Link your local development project to a hosted Supabase project.
        
        PostgREST configurations are fetched from the Supabase platform and validated against your local configuration file.
        
        Optionally, database settings can be validated if you provide a password. Your database password is saved in native credentials storage if available.
        
        > If you do not want to be prompted for the database password, such as in a CI environment, you may specify it explicitly via the `SUPABASE_DB_PASSWORD` environment variable.
        
        Some commands like `db dump`, `db push`, and `db pull` require your project to be linked first.
        
      • login.md 695 B
        ## supabase-login
        
        Connect the Supabase CLI to your Supabase account by logging in with your [personal access token](https://supabase.com/dashboard/account/tokens).
        
        Your access token is stored securely in [native credentials storage](https://github.com/zalando/go-keyring#dependencies). If native credentials storage is unavailable, it will be written to a plain text file at `<SUPABASE_HOME or ~/.supabase>/access-token`.
        
        > If this behavior is not desired, such as in a CI environment, you may skip login by specifying the `SUPABASE_ACCESS_TOKEN` environment variable in other commands.
        
        The Supabase CLI uses the stored token to access Management APIs for projects, functions, secrets, etc.
        
      • network-bans.md 230 B
        ## supabase-network-bans
        
        Network bans are IPs that get temporarily blocked if their traffic pattern looks abusive (e.g. multiple failed auth attempts).
        
        The subcommands help you view the current bans, and unblock IPs if desired.
        
      • projects.md 477 B
        ## supabase-projects
        
        Provides tools for creating and managing your Supabase projects.
        
        This command group allows you to list all projects in your organizations, create new projects, delete existing projects, and retrieve API keys. These operations help you manage your Supabase infrastructure programmatically without using the dashboard.
        
        Project management via CLI is especially useful for automation scripts and when you need to provision environments in a repeatable way.
        
      • secrets.md 476 B
        ## supabase-secrets
        
        Provides tools for managing environment variables and secrets for your Supabase project.
        
        This command group allows you to set, unset, and list secrets that are securely stored and made available to Edge Functions as environment variables.
        
        Secrets management through the CLI is useful for:
        
        - Setting environment-specific configuration
        - Managing sensitive credentials securely
        
        Secrets can be set individually or loaded from .env files for convenience.
        
      • start.md 850 B
        ## supabase-start
        
        Starts the Supabase local development stack.
        
        Requires `supabase/config.toml` to be created in your current working directory by running `supabase init`.
        
        All service containers are started by default. You can exclude those not needed by passing in `-x` flag. To exclude multiple containers, either pass in a comma separated string, such as `-x gotrue,imgproxy`, or specify `-x` flag multiple times.
        
        > It is recommended to have at least 7GB of RAM to start all services.
        
        Health checks are automatically added to verify the started containers. Use `--ignore-health-check` flag to ignore these errors.
        
        > If the CLI is running inside a dev container with the Docker socket bind-mounted, set the `SUPABASE_SERVICES_HOSTNAME` environment variable to the hostname reachable from inside that container, such as `host.docker.internal`.
        
      • status.md 432 B
        ## supabase-status
        
        Shows status of the Supabase local development stack.
        
        Requires the local development stack to be started by running `supabase start` or `supabase db start`.
        
        You can export the connection parameters for [initializing supabase-js](https://supabase.com/docs/reference/javascript/initializing) locally by specifying the `-o env` flag. Supported parameters include `JWT_SECRET`, `ANON_KEY`, and `SERVICE_ROLE_KEY`.
        
      • stop.md 475 B
        ## supabase-stop
        
        Stops the Supabase local development stack.
        
        Requires `supabase/config.toml` to be created in your current working directory by running `supabase init`.
        
        All Docker resources are maintained across restarts. Use `--no-backup` flag to reset your local development data between restarts.
        
        Use the `--all` flag to stop all local Supabase projects instances on the machine. Use with caution with `--no-backup` as it will delete all supabase local projects data.
        
      • vanity-subdomains.md 149 B
        ## supabase-vanity-subdomains
        
        Manage vanity subdomains for Supabase projects.
        
        Usage of vanity subdomains and custom domains is mutually exclusive.
        
    • config
      • diff.md 2.3 KB
        # supabase-config-diff
        
        Shows the configuration differences between the local `supabase/config.toml` and the effective configuration of a remote project or branch. Read-only: it never modifies the local file or any remote configuration.
        
        Pass `--project-ref` to compare against a specific project, or the name (or UUID) of a branch of the currently linked project — values that are exactly 20 lowercase letters are always treated as project refs. Without it, the linked project is the target. When the target ref matches a `[remotes.*]` block's `project_id`, that block's merged config is the local side of the comparison.
        
        Only platform-managed properties are compared. Local-stack-only sections — `[studio]`, `[analytics]`, `[functions]`, `[edge_runtime]`, port numbers, image version pins, `[db.migrations]`, and similar — have no hosted counterpart and are never reported, whether or not your file declares them.
        
        Each difference is classified as `update` (the file declares a value that differs remotely), `remote-only` (the remote differs while the file is silent — the shown local value is the schema default a `config push` would write), or `local-only` (the file declares a value the remote did not report). `(unset)` means the local side has no value at all; `(not returned)` means the response did not carry the property. Secret values are never compared — the platform only reports digests — and are listed in a masked-credentials note instead, as are declared properties that `config push` cannot communicate and any block the response omitted entirely.
        
        Local values are shown as the configuration your file would produce once pushed, not its literal spelling: a duration written as `"1m"` renders as `"1m0s"`, and byte sizes are shown in the units you wrote.
        
        With `--exit-code`, the command exits `2` when any difference is found, keeping exit `1` for errors — so scripts can distinguish drift from failure.
        
        Machine-readable output is available through `--output-format json|stream-json` — a versioned payload (`schema_version`, `config_schema`, `target`, `scope`, `changes[]`, `masked[]`, `unmanaged[]`, `counts`) with per-change `path`s as segment arrays. The legacy global `-o`/`--output` flag is not supported by this command; use `--output-format json|stream-json` instead.
        
      • pull.md 8 KB
        # supabase-config-pull
        
        Writes the effective configuration of a remote project or branch into the local `supabase/config.toml`/`config.json` — the write side of `supabase config diff`. Every write is a surgical, format-preserving edit: comments, key ordering, and quoting elsewhere in the file are left untouched, and only the values that actually change are rewritten.
        
        Pass `--project-ref` to pull from a specific project, or the name (or UUID) of a branch of the currently linked project — values that are exactly 20 lowercase letters are always treated as project refs. Without it, the linked project is the target.
        
        Where a pulled value lands depends on whether the target is already tracked by a `[remotes.*]` block, not on how you named it: if any block's `project_id` already matches the resolved ref, that block is reused — whatever its own label — and every value lands there. Otherwise, if the target was named as a branch, a new `[remotes.<branch-name>]` block is created (a branch resolved by UUID falls back to the project ref itself as its label). Only when neither applies — a bare `--project-ref` naming a project directly, or the linked project with no branch involved — do values land at the config root. `--remote-label` overrides the block config pull would otherwise reuse or create; naming a block that already tracks a different project, or naming nothing while a different block already tracks this exact ref, is an error rather than a silent overwrite. A `[remotes.*]` block whose `project_id` is an `env(...)` reference that merely _resolves_ to the target ref is never reused or rewritten — that is a hard error naming the variable, since a value written there would never actually take effect on the next load. Creating a new block always writes its `project_id`, even when every value it would otherwise carry already matches the local defaults — otherwise the block could never be reused on a later pull.
        
        Writing to the config root can also affect `supabase start`: a handful of root-scoped settings — `auth.site_url`, `db.settings.*`, `db.major_version` (which changes what `supabase start` boots), `db.pooler.*`, and similar — also govern the local stack, so pulling a hosted value into them is a real change to local dev behavior, not just a record of the hosted project's own setting. `config pull` warns about this rather than refusing; writing the same value into a `[remotes.*]` block is unaffected. Passing `--remote-label` is the escape hatch: it diverts what would otherwise be a root-bound pull into a `[remotes.<label>]` block instead, leaving local dev untouched.
        
        Several kinds of values are never written, and are reported instead of silently skipped: a value whose local declaration resolves from an `env(VAR)` reference (reported by variable name — replace the reference yourself, or pass `--remote-label` to target a different block); a value the REMOTE itself spells as an `env(VAR)` reference (`remote_env_reference`) — the loader would resolve it against the local environment on the next load, so writing it verbatim would let a remote value read whatever this machine's environment holds at that name; secret values, which the platform never returns in plaintext (a masked-credentials note); a value the file declares that the remote does not report (`local-only` — never removed); and a handful of already-declared properties `config push` cannot communicate back at all (an unmanaged note). Local-stack-only sections — `[studio]`, `[analytics]`, `[functions]`, `[edge_runtime]`, port numbers, image version pins, and similar — have no hosted counterpart and are never touched. One family of properties is written despite `config push` having no way to send it back (`auth.oauth_server`, disabled `storage.analytics`/`storage.vector`, …) — pulling still records the hosted value, with a warning that it cannot be pushed back.
        
        `config pull` never writes a `config.toml`/`.json` it cannot load back on the next command. Pulling a value that GATES other declared fields — e.g. flipping a disabled provider's `enabled` on — also pulls its now-required sibling values into the same write (not just the gate), so the file never comes out half-configured. When one of those siblings genuinely can't be supplied — the remote doesn't report it, or supplying it would still leave a REQUIRED value missing — the whole toggle is skipped instead, reported with a new reason (`requires values pull cannot write` in text output, `would_invalidate` in the machine payload) plus a note naming the missing field(s) and, when a missing field's local spelling is itself an unresolved `env(VAR)` reference, the exact environment variable to set before rerunning.
        
        `--dry-run` computes and prints exactly what `config diff` would show, then stops — no git check, no prompt, no write. `--output-format json|stream-json` never prompts at all — it returns the confirmation's default value without reading anything, so use `--dry-run` for a preview in those shapes rather than relying on the prompt. A non-interactive run in the default text format (no TTY on stdin) still prints the confirmation to stderr and reads a single line from piped stdin: an explicit `y`/`n` answer is honored, and an empty or unparseable line falls back to the default. `--yes` (or `SUPABASE_YES`) answers the confirmation prompt without asking on an interactive TTY; it does not bypass the uncommitted-changes guard — on the contrary, `--yes` together with uncommitted (or untracked) changes aborts instead of silently overwriting them, since no human is left to read the warning. `--force` writes even when `supabase/config.toml` has uncommitted or untracked changes in git — without it, an interactive run's prompt defaults to "no" instead of "yes", and every other case (non-interactive text, machine-format, or `--yes` on any TTY) aborts outright.
        
        A second `config pull` against an already-tracked, unchanged remote always writes nothing — that convergence is the design's own acceptance property, not a special case. It never even checks for uncommitted local changes to the config file in that case, since there is nothing to write either way. A target that isn't tracked yet (a branch or `--remote-label` name with no existing `[remotes.*]` block) still creates that block on its first pull, even when every value it carries already matches the local defaults — it's the second pull against that now-tracked block that then writes nothing.
        
        ## Example
        
        Given `supabase/config.toml`:
        
        ```toml
        project_id = "abcdefghijklmnopqrst"
        
        [api]
        enabled = true
        max_rows = 1000
        ```
        
        `supabase config pull --project-ref staging`, where `staging` is a branch of the linked project and no existing `[remotes.*]` block already tracks it, creates a new block at the end of the file — `max_rows` lands under its own `[remotes.staging.api]` sub-table, the same way `[api]` itself is a sub-table of the document root, not a key directly under `[remotes.staging]`:
        
        ```toml
        project_id = "abcdefghijklmnopqrst"
        
        [api]
        enabled = true
        max_rows = 1000
        
        [remotes.staging]
        project_id = "cccccccccccccccccccc"
        
        [remotes.staging.api]
        max_rows = 250
        ```
        
        Running the same command again finds no differences and writes nothing.
        
        Machine-readable output is available through `--output-format json|stream-json` — a versioned payload (`schema_version`, `config_schema`, `config_path`, `format`, `target`, `destination`, `dry_run`, `wrote`, `scope`, `changes[]`, `warnings[]`, `masked[]`, `unmanaged[]`, `counts`) with per-change `path`s as segment arrays, each carrying `written` and, when unwritten, a `skipped_reason` (`env_reference | local_only | remote_env_reference | unwritable | would_invalidate | declined | dry_run`). A `would_invalidate` warning additionally carries `missing_fields` (`[{path, env_variable?}]`) naming what actually blocked the family. The legacy global `-o`/`--output` flag is not supported by this command; use `--output-format json|stream-json` instead. Note: the payload spells the root scope `"base"` (`target.local_scope`), while text output calls the same thing `config root`.
        
      • push.md 1.5 KB
        # supabase-config-push
        
        Updates the configurations of a linked Supabase project with the local `supabase/config.toml` file.
        
        This command allows you to manage project configuration as code by defining settings locally and then pushing them to your remote project.
        
        Pass `--project-ref` to push to a specific project, or the name (or UUID) of a branch of the currently linked project — values that are exactly 20 lowercase letters are always treated as project refs. Without it, the linked project is the target.
        
        Before anything is pushed, the command reports the project it resolved — its name and ref. When the resolved target is a preview branch that was only _inferred_ (for example after `supabase link <branch-name>`, or via `SUPABASE_PROJECT_ID`) rather than named on this invocation, it says so, names the branch and its parent project where they can be resolved, and asks for confirmation first. Declining — including on an unattended run with no `--yes` and no piped answer — fails the command rather than pushing. Pass `--yes` (or set `SUPABASE_YES`) to skip that confirmation in CI and scripted runs.
        
        An explicit `--project-ref <branch-name-or-uuid>` on the same invocation skips the confirmation entirely (the target is still echoed) — naming the branch yourself already counts as confirming it. Because the confirmation reads one line of piped input just like any other prompt, a script piping multiple `y`/`n` answers to an _inferred_ branch target needs one extra leading answer for it, ahead of the per-service prompts it already answers.
        
    • db
      • advisors.md 174 B
        ## supabase-db-advisors
        
        Inspects the database for common security and performance issues such as missing RLS policies, unindexed foreign keys, exposed auth.users, and more.
        
      • diff.md 2.7 KB
        ## supabase-db-diff
        
        Diffs schema changes made to the local or remote database.
        
        Requires the local development stack to be running when diffing against the local database. To diff against a remote or self-hosted database, specify the `--linked` or `--db-url` flag respectively.
        
        Runs [djrobstep/migra](https://github.com/djrobstep/migra) in a container to compare schema differences between the target database and a shadow database. The shadow database is created by applying migrations in local `supabase/migrations` directory in a separate container. Output is written to stdout by default. For convenience, you can also save the schema diff as a new migration file by passing in `-f` flag.
        
        Explicit `--from`/`--to` mode always uses pg-delta. In this mode, `-f` is ignored and stdout (or `--output`) is a flattened representation for review, not a portable apply script. Do not apply it directly with plain `psql -f`: transactional units can contain `SET LOCAL` preambles that only take effect inside a transaction, while plans that mix transactional and non-transactional units cannot safely be wrapped in one transaction. To create an applicable migration, use normal target mode with `supabase db diff -f <name>`, then apply it through `supabase db reset` locally or `supabase db push` against the linked project. These paths preserve the plan's per-unit transaction semantics.
        
        By default, all schemas in the target database are diffed. Use the `--schema public,extensions` flag to restrict diffing to a subset of schemas.
        
        Projects created by a recent `supabase init` default to the pg-delta diff engine (`[experimental.pgdelta] enabled = true` in `config.toml`). Existing projects are unaffected and keep using migra unless they opt in. To fall back to the legacy migra engine, set `enabled = false` under `[experimental.pgdelta]`, or pass `--use-migra` for a single run.
        
        With the bundled pg-delta engine, diff SQL defaults to uppercase keywords, indent 2, a maximum width of 180, trailing commas, and column/key alignment, matching its declarative export. When `-f` writes migrations, execution-aware transaction semantics are preserved as ordered per-unit files; non-transactional units carry a directive that the CLI apply path honors. Flattened review output retains the rendered SQL and preambles, but not the unit boundaries supplied to a migration runner. Configure overrides with `[experimental.pgdelta] format_options`, or set `format_options = "null"` to emit raw, unformatted statements.
        
        While the diff command is able to capture most schema changes, there are cases where it is known to fail. Currently, this could happen if you schema contains:
        
        - Changes to publication
        - Changes to storage buckets
        - Views with `security_invoker` attributes
        
      • dump.md 926 B
        ## supabase-db-dump
        
        Dumps contents from a remote database.
        
        Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag.
        
        Runs `pg_dump` in a container with additional flags to exclude Supabase managed schemas. The ignored schemas include auth, storage, and those created by extensions.
        
        The default dump does not contain any data or custom roles. To dump those contents explicitly, specify either the `--data-only` and `--role-only` flag.
        
        ### Note on Privilege Migration
        
        When restoring to a new project, tables inherit ALL privileges from default privileges in the target database. To preserve specific privileges from your dump, revoke defaults before restoring:
        
        ```sql
        -- Run BEFORE restoring your schema
        ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated;
        ```
        
      • lint.md 1003 B
        ## supabase-db-lint
        
        Lints local database for schema errors.
        
        Requires the local development stack to be running when linting against the local database. To lint against a remote or self-hosted database, specify the `--linked` or `--db-url` flag respectively.
        
        Runs `plpgsql_check` extension in the local Postgres container to check for errors in all schemas. The default lint level is `warning` and can be raised to error via the `--level` flag.
        
        To lint against specific schemas only, pass in the `--schema` flag.
        
        The `--fail-on` flag can be used to control when the command should exit with a non-zero status code. The possible values are:
        
        - `none` (default): Always exit with a zero status code, regardless of lint results.
        - `warning`: Exit with a non-zero status code if any warnings or errors are found.
        - `error`: Exit with a non-zero status code only if errors are found.
        
        This flag is particularly useful in CI/CD pipelines where you want to fail the build based on certain lint conditions.
        
      • pull.md 3.4 KB
        # supabase-db-pull
        
        Pulls schema changes from a remote database. A new migration file will be created under `supabase/migrations` directory.
        
        Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag.
        
        > Note this command requires Docker Desktop (or a running Docker daemon), as it starts a local Postgres container to diff your remote schema.
        
        Optionally, a new row can be inserted into the migration history table to reflect the current state of the remote database.
        
        If no entries exist in the migration history table, the default diff engine uses `pg_dump` to capture all contents of the remote schemas you have created. Otherwise, this command will only diff schema changes against the remote database, similar to running `db diff --linked`.
        
        Pass `--diff-engine pg-delta` to keep the migration-file `db pull` workflow while using pg-delta for the shadow diff step. On initial pull, pg-delta replaces `pg_dump` and produces the full migration from the shadow diff alone. Pass `--declarative` to switch to the declarative pg-delta export workflow instead.
        
        pg-delta plans are execution-aware: when a plan crosses a transaction boundary — for example `ALTER TYPE ... ADD VALUE` followed by a statement that uses the new enum value, which cannot run in the same transaction — `db pull` writes one ordered migration file per plan unit instead of a single file (for example `<ts>_remote_schema_schema_changes.sql` and `<ts+1s>_remote_schema_after_enum_values.sql`), each recorded in the migration history. The common case (a single unit) still produces exactly one `<ts>_remote_schema.sql` file.
        
        By default the emitted SQL is formatted with the same settings the declarative export uses (uppercase keywords, wrapped at a max width of 180, indented and column-aligned). Configure overrides with `[experimental.pgdelta] format_options` in `config.toml`, or set `format_options = "null"` to opt out and emit raw, unformatted statements.
        
        When `[experimental.pgdelta] enabled = true` (the default for projects created by a recent `supabase init`), the migration-file `db pull` workflow uses pg-delta for the shadow diff step by default; it does not switch to declarative output. Existing projects without the section are unaffected and keep using migra. To fall back to the legacy migra engine, set `enabled = false` under `[experimental.pgdelta]`, or pass `--diff-engine migra` for a single run.
        
        When pulling from a remote database with `--db-url`, prefer a direct connection (`db.<project-ref>.supabase.co:5432`) over the connection pooler so pg-delta can introspect the full catalog reliably.
        
        ## Debugging empty pg-delta pulls
        
        If `db pull --diff-engine pg-delta` reports `No schema changes found` but you expect schema output, set `PGDELTA_DEBUG=1` before running the command. Unlike `--debug`, this keeps SSL enabled for remote Supabase connections.
        
        ```sh
        PGDELTA_DEBUG=1 supabase db pull --db-url "$DATABASE_URL" --diff-engine pg-delta
        ```
        
        When pg-delta returns zero statements, the CLI writes a debug bundle under `supabase/.temp/pgdelta/v2/debug/<timestamp>-diff/` containing the source/desired catalog snapshots, the plan, and coverage diagnostics. Catalog files are not written during normal `db pull` runs.
        
        For TLS tracing without disabling SSL, use `SUPABASE_SSL_DEBUG=true` alongside `PGDELTA_DEBUG=1`.
        
      • push.md 843 B
        ## supabase-db-push
        
        Pushes all local migrations to a remote database.
        
        Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag.
        
        The first time this command is run, a migration history table will be created under `supabase_migrations.schema_migrations`. After successfully applying a migration, a new row will be inserted into the migration history table with timestamp as its unique id. Subsequent pushes will skip migrations that have already been applied.
        
        If you need to mutate the migration history table, such as deleting existing entries or inserting new entries without actually running the migration, use the `migration repair` command.
        
        Use the `--dry-run` flag to view the list of changes before applying.
        
      • query.md 337 B
        ## supabase-db-query
        
        Execute a SQL query against the local or linked database.
        
        When used by an AI coding agent (auto-detected or via --agent=yes), the default
        output format is JSON with an untrusted data warning envelope. When used by a
        human (--agent=no or no agent detected), the default output format is table
        without the envelope.
        
      • reset.md 1.3 KB
        ## supabase-db-reset
        
        Resets the local database to a clean state.
        
        Requires the local development stack to be started by running `supabase start`.
        
        Recreates the local Postgres container and applies all local migrations found in `supabase/migrations` directory. If test data is defined in `supabase/seed.sql`, it will be seeded after the migrations are run. Any other data or schema changes made during local development will be discarded.
        
        Use the `--no-seed` flag to skip seeding entirely. To override `[db.seed].sql_paths` for a single reset, pass one or more `--sql-paths` flags. Each value accepts the same file path or glob pattern syntax as `sql_paths`, relative to the `supabase` directory. Passing `--sql-paths` force-enables seeding for that reset even when `[db.seed].enabled = false`.
        
        When running db reset with `--linked` or `--db-url` flag, a SQL script is executed to identify and drop all user created entities in the remote database. Since Postgres roles are cluster level entities, any custom roles created through the dashboard or `supabase/roles.sql` will not be deleted by remote reset.
        
        If you combine `--sql-paths` with `--linked` or `--db-url`, the override seed files are applied to the selected remote database after migrations. Use this only when you intend to seed that remote target.
        
      • schema-declarative-generate.md 1.2 KB
        ## supabase-db-schema-declarative-generate
        
        Generate declarative schema files from a database.
        
        Exports the schema of a live database (local, linked, or custom URL) into SQL files under the declarative schema directory. This is the entrypoint for bootstrapping declarative mode.
        
        The bundled pg-delta engine writes one directory per schema at the root of that directory (`supabase/schemas/public/tables/users.sql`, `supabase/schemas/public/schema.sql`), with cluster-level objects that belong to no schema under a reserved `_cluster/` directory (`supabase/schemas/_cluster/roles.sql`). A schema literally named `_cluster` or `_custom`, in any casing, has its leading underscore percent-encoded (`%5Fcluster/`) so it can never claim a directory the export owns. Hand-authored SQL that pg-delta does not model belongs in `_custom/`, which the export never writes to and never prunes.
        
        Emitted SQL uses the same default format as `db pull` (uppercase keywords, indent 2, width 180, column-aligned). Override with `[experimental.pgdelta] format_options`, or set `format_options = "null"` for raw statements.
        
        Requires `--experimental` flag or `[experimental.pgdelta] enabled = true` in config.
        
      • schema-declarative-sync.md 413 B
        ## supabase-db-schema-declarative-sync
        
        Generate a new migration by diffing your declarative schema files against the current migration state.
        
        When no declarative schema exists yet, the command offers to run `generate` first. After computing the diff, you can optionally name the migration and apply it to the local database.
        
        Requires `--experimental` flag or `[experimental.pgdelta] enabled = true` in config.
        
    • domains
      • activate.md 523 B
        ## supabase-domains-activate
        
        Activates the custom hostname configuration for a project.
        
        This reconfigures your Supabase project to respond to requests on your custom hostname.
        
        After the custom hostname is activated, your project's third-party auth providers will no longer function on the Supabase-provisioned subdomain. Please refer to [Prepare to activate your domain](/docs/guides/platform/custom-domains#prepare-to-activate-your-domain) section in our documentation to learn more about the steps you need to follow.
        
    • functions
      • new.md 510 B
        ## supabase-functions-new
        
        Creates a new Edge Function with boilerplate code in the `supabase/functions` directory.
        
        This command generates a starter TypeScript file with the necessary Deno imports and a basic function structure. The function is created as a new directory with the name you specify, containing an `index.ts` file with the function code.
        
        After creating the function, you can edit it locally and then use `supabase functions serve` to test it before deploying with `supabase functions deploy`.
        
      • serve.md 1.9 KB
        ## supabase-functions-serve
        
        Serve all Functions locally.
        
        `supabase functions serve` command includes additional flags to assist developers in debugging Edge Functions via the v8 inspector protocol, allowing for debugging via Chrome DevTools, VS Code, and IntelliJ IDEA for example. Refer to the [docs guide](/docs/guides/functions/debugging-tools) for setup instructions.
        
        1. `--inspect`
           - Alias of `--inspect-mode brk`.
        
        2. `--inspect-mode [ run | brk | wait ]`
           - Activates the inspector capability.
           - `run` mode simply allows a connection without additional behavior. It is not ideal for short scripts, but it can be useful for long-running scripts where you might occasionally want to set breakpoints.
           - `brk` mode same as `run` mode, but additionally sets a breakpoint at the first line to pause script execution before any code runs.
           - `wait` mode similar to `brk` mode, but instead of setting a breakpoint at the first line, it pauses script execution until an inspector session is connected.
        
        3. `--inspect-main`
           - Can only be used when one of the above two flags is enabled.
           - By default, creating an inspector session for the main worker is not allowed, but this flag allows it.
           - Other behaviors follow the `inspect-mode` flag mentioned above.
        
        Additionally, the following properties can be customized via `supabase/config.toml` under `edge_runtime` section.
        
        1. `inspector_port`
           - The port used to listen to the Inspector session, defaults to 8083.
        2. `policy`
           - A value that indicates how the edge-runtime should forward incoming HTTP requests to the worker.
           - `per_worker` allows multiple HTTP requests to be forwarded to a worker that has already been created.
           - `oneshot` will force the worker to process a single HTTP request and then exit. (Debugging purpose, This is especially useful if you want to reflect changes you've made immediately.)
        
    • inspect
      • db-bloat.md 1.3 KB
        ## db-bloat
        
        This command displays an estimation of table "bloat" - Due to Postgres' [MVCC](https://www.postgresql.org/docs/current/mvcc.html) when data is updated or deleted new rows are created and old rows are made invisible and marked as "dead tuples". Usually the [autovaccum](https://supabase.com/docs/guides/platform/database-size#vacuum-operations) process will asynchronously clean the dead tuples. Sometimes the autovaccum is unable to work fast enough to reduce or prevent tables from becoming bloated. High bloat can slow down queries, cause excessive IOPS and waste space in your database.
        
        Tables with a high bloat ratio should be investigated to see if there are vacuuming is not quick enough or there are other issues.
        
        ```
            TYPE  │ SCHEMA NAME │        OBJECT NAME         │ BLOAT │ WASTE
          ────────┼─────────────┼────────────────────────────┼───────┼─────────────
            table │ public      │ very_bloated_table         │  41.0 │ 700 MB
            table │ public      │ my_table                   │   4.0 │ 76 MB
            table │ public      │ happy_table                │   1.0 │ 1472 kB
            index │ public      │ happy_table::my_nice_index │   0.7 │ 880 kB
        ```
        
      • db-blocking.md 1.2 KB
        ## db-blocking
        
        This command shows you statements that are currently holding locks and blocking, as well as the statement that is being blocked. This can be used in conjunction with `inspect db locks` to determine which statements need to be terminated in order to resolve lock contention.
        
        ```
            BLOCKED PID │ BLOCKING STATEMENT           │ BLOCKING DURATION │ BLOCKING PID │ BLOCKED STATEMENT                                                                      │ BLOCKED DURATION
          ──────────────┼──────────────────────────────┼───────────────────┼──────────────┼────────────────────────────────────────────────────────────────────────────────────────┼───────────────────
            253         │ select count(*) from mytable │ 00:00:03.838314   │        13495 │ UPDATE "mytable" SET "updated_at" = '2023─08─03 14:07:04.746688' WHERE "id" = 83719341 │ 00:00:03.821826
        ```
        
      • db-cache-hit.md 1.3 KB
        # db-cache-hit
        
        This command provides information on the efficiency of the buffer cache and how often your queries have to go hit the disk rather than reading from memory. Information on both index reads (`index hit rate`) as well as table reads (`table hit rate`) are shown. In general, databases with low cache hit rates perform worse as it is slower to go to disk than retrieve data from memory. If your table hit rate is low, this can indicate that you do not have enough RAM and you may benefit from upgrading to a larger compute addon with more memory. If your index hit rate is low, this may indicate that there is scope to add more appropriate indexes.
        
        The hit rates are calculated as a ratio of number of table or index blocks fetched from the postgres buffer cache against the sum of cached blocks and uncached blocks read from disk.
        
        On smaller compute plans (free, small, medium), a ratio of below 99% can indicate a problem. On larger plans the hit rates may be lower but performance will remain constant as the data may use the OS cache rather than Postgres buffer cache.
        
        ```
                 NAME      │  RATIO
          ─────────────────┼───────────
            index hit rate │ 0.996621
            table hit rate │ 0.999341
        ```
        
      • db-calls.md 1.3 KB
        # db-calls
        
        This command is much like the `supabase inspect db outliers` command, but ordered by the number of times a statement has been called.
        
        You can use this information to see which queries are called most often, which can potentially be good candidates for optimisation.
        
        ```
        
                                QUERY                      │ TOTAL EXECUTION TIME │ PROPORTION OF TOTAL EXEC TIME │ NUMBER CALLS │  SYNC IO TIME
          ─────────────────────────────────────────────────┼──────────────────────┼───────────────────────────────┼──────────────┼──────────────────
            SELECT * FROM users WHERE id = $1              │ 14:50:11.828939      │ 89.8%                         │  183,389,757 │ 00:00:00.002018
            SELECT * FROM user_events                      │ 01:20:23.466633      │ 1.4%                          │       78,325 │ 00:00:00
            INSERT INTO users (email, name) VALUES ($1, $2)│ 00:40:11.616882      │ 0.8%                          │       54,003 │ 00:00:00.000322
        
        ```
        
      • db-index-sizes.md 660 B
        # db-index-sizes
        
        This command displays the size of each each index in the database. It is calculated by taking the number of pages (reported in `relpages`) and multiplying it by the page size (8192 bytes).
        
        ```
                      NAME              │    SIZE
          ──────────────────────────────┼─────────────
            user_events_index           │ 2082 MB
            job_run_details_pkey        │ 3856 kB
            schema_migrations_pkey      │ 16 kB
            refresh_tokens_token_unique │ 8192 bytes
            users_instance_id_idx       │ 0 bytes
            buckets_pkey                │ 0 bytes
        ```
        
      • db-index-usage.md 968 B
        # db-index-usage
        
        This command provides information on the efficiency of indexes, represented as what percentage of total scans were index scans. A low percentage can indicate under indexing, or wrong data being indexed.
        
        ```
               TABLE NAME     │ PERCENTAGE OF TIMES INDEX USED │ ROWS IN TABLE
          ────────────────────┼────────────────────────────────┼────────────────
            user_events       │                             99 │       4225318
            user_feed         │                             99 │       3581573
            unindexed_table   │                              0 │        322911
            job               │                            100 │         33242
            schema_migrations │                             97 │             0
            migrations        │ Insufficient data              │             0
        ```
        
      • db-locks.md 1.1 KB
        # db-locks
        
        This command displays queries that have taken out an exclusive lock on a relation. Exclusive locks typically prevent other operations on that relation from taking place, and can be a cause of "hung" queries that are waiting for a lock to be granted.
        
        If you see a query that is hanging for a very long time or causing blocking issues you may consider killing the query by connecting to the database and running `SELECT pg_cancel_backend(PID);` to cancel the query. If the query still does not stop you can force a hard stop by running `SELECT pg_terminate_backend(PID);`
        
        ```
             PID   │ RELNAME │ TRANSACTION ID │ GRANTED │                  QUERY                  │   AGE
          ─────────┼─────────┼────────────────┼─────────┼─────────────────────────────────────────┼───────────
            328112 │ null    │              0 │ t       │ SELECT * FROM logs;                     │ 00:04:20
        ```
        
      • db-long-running-queries.md 1 KB
        # db-long-running-queries
        
        This command displays currently running queries, that have been running for longer than 5 minutes, descending by duration. Very long running queries can be a source of multiple issues, such as preventing DDL statements completing or vacuum being unable to update `relfrozenxid`.
        
        ```
          PID  │     DURATION    │                                         QUERY
        ───────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────────────
         19578 | 02:29:11.200129 | EXPLAIN SELECT  "students".* FROM "students"  WHERE "students"."id" = 1450645 LIMIT 1
         19465 | 02:26:05.542653 | EXPLAIN SELECT  "students".* FROM "students"  WHERE "students"."id" = 1889881 LIMIT 1
         19632 | 02:24:46.962818 | EXPLAIN SELECT  "students".* FROM "students"  WHERE "students"."id" = 1581884 LIMIT 1
        ```
        
      • db-outliers.md 1.9 KB
        # db-outliers
        
        This command displays statements, obtained from `pg_stat_statements`, ordered by the amount of time to execute in aggregate. This includes the statement itself, the total execution time for that statement, the proportion of total execution time for all statements that statement has taken up, the number of times that statement has been called, and the amount of time that statement spent on synchronous I/O (reading/writing from the file system).
        
        Typically, an efficient query will have an appropriate ratio of calls to total execution time, with as little time spent on I/O as possible. Queries that have a high total execution time but low call count should be investigated to improve their performance. Queries that have a high proportion of execution time being spent on synchronous I/O should also be investigated.
        
        ```
        
                         QUERY                   │ EXECUTION TIME   │ PROPORTION OF EXEC TIME │ NUMBER CALLS │ SYNC IO TIME
        ─────────────────────────────────────────┼──────────────────┼─────────────────────────┼──────────────┼───────────────
         SELECT * FROM archivable_usage_events.. │ 154:39:26.431466 │ 72.2%                   │ 34,211,877   │ 00:00:00
         COPY public.archivable_usage_events (.. │ 50:38:33.198418  │ 23.6%                   │ 13           │ 13:34:21.00108
         COPY public.usage_events (id, reporte.. │ 02:32:16.335233  │ 1.2%                    │ 13           │ 00:34:19.784318
         INSERT INTO usage_events (id, retaine.. │ 01:42:59.436532  │ 0.8%                    │ 12,328,187   │ 00:00:00
         SELECT * FROM usage_events WHERE (alp.. │ 01:18:10.754354  │ 0.6%                    │ 102,114,301  │ 00:00:00
        ```
        
      • db-replication-slots.md 1.3 KB
        # db-replication-slots
        
        This command shows information about [logical replication slots](https://www.postgresql.org/docs/current/logical-replication.html) that are setup on the database. It shows if the slot is active, the state of the WAL sender process ('startup', 'catchup', 'streaming', 'backup', 'stopping') the replication client address and the replication lag in GB.
        
        This command is useful to check that the amount of replication lag is as low as possible, replication lag can occur due to network latency issues, slow disk I/O, long running transactions or lack of ability for the subscriber to consume WAL fast enough.
        
        ```
                               NAME                    │ ACTIVE │ STATE   │ REPLICATION CLIENT ADDRESS │ REPLICATION LAG GB
          ─────────────────────────────────────────────┼────────┼─────────┼────────────────────────────┼─────────────────────
            supabase_realtime_replication_slot         │ t      │ N/A     │ N/A                        │                  0
            datastream                                 │ t      │ catchup │ 24.201.24.106              │                 45
        ```
        
      • db-role-connections.md 1.6 KB
        # db-role-connections
        
        This command shows the number of active connections for each database roles to see which specific role might be consuming more connections than expected.
        
        This is a Supabase specific command. You can see this breakdown on the dashboard as well:
        https://app.supabase.com/project/_/database/roles
        
        The maximum number of active connections depends [on your instance size](https://supabase.com/docs/guides/platform/compute-add-ons). You can [manually overwrite](https://supabase.com/docs/guides/platform/performance#allowing-higher-number-of-connections) the allowed number of connection but it is not advised.
        
        ```
        
        
                    ROLE NAME         │ ACTIVE CONNCTION
          ────────────────────────────┼───────────────────
            authenticator             │                5
            postgres                  │                5
            supabase_admin            │                1
            pgbouncer                 │                1
            anon                      │                0
            authenticated             │                0
            service_role              │                0
            dashboard_user            │                0
            supabase_auth_admin       │                0
            supabase_storage_admin    │                0
            supabase_functions_admin  │                0
            pgsodium_keyholder        │                0
            pg_read_all_data          │                0
            pg_write_all_data         │                0
            pg_monitor                │                0
        
        Active connections 12/90
        
        ```
        
      • db-seq-scans.md 720 B
        # db-seq-scans
        
        This command displays the number of sequential scans recorded against all tables, descending by count of sequential scans. Tables that have very high numbers of sequential scans may be underindexed, and it may be worth investigating queries that read from these tables.
        
        ```
                          NAME               │ COUNT
          ───────────────────────────────────┼─────────
            emails                           │ 182435
            users                            │  25063
            job_run_details                  │     60
            schema_migrations                │      0
            migrations                       │      0
        ```
        
      • db-table-index-sizes.md 627 B
        # db-table-index-sizes
        
        This command displays the total size of indexes for each table. It is calculated by using the system administration function `pg_indexes_size()`.
        
        ```
                         TABLE               │ INDEX SIZE
          ───────────────────────────────────┼─────────────
            job_run_details                  │ 10104 kB
            users                            │ 128 kB
            job                              │ 32 kB
            instances                        │ 8192 bytes
            http_request_queue               │ 0 bytes
        ```
        
      • db-table-record-counts.md 636 B
        # db-table-record-counts
        
        This command displays an estimated count of rows per table, descending by estimated count. The estimated count is derived from `n_live_tup`, which is updated by vacuum operations. Due to the way `n_live_tup` is populated, sparse vs. dense pages can result in estimations that are significantly out from the real count of rows.
        
        ```
               NAME    │ ESTIMATED COUNT
          ─────────────┼──────────────────
            logs       │          322943
            emails     │            1103
            job        │               1
            migrations │               0
        ```
        
      • db-table-sizes.md 756 B
        # db-table-sizes
        
        This command displays the size of each table in the database. It is calculated by using the system administration function `pg_table_size()`, which includes the size of the main data fork, free space map, visibility map and TOAST data. It does not include the size of the table's indexes.
        
        ```
                          NAME               │    SIZE
          ───────────────────────────────────┼─────────────
            job_run_details                  │ 385 MB
            emails                           │ 584 kB
            job                              │ 40 kB
            sessions                         │ 0 bytes
            prod_resource_notifications_meta │ 0 bytes
        ```
        
      • db-total-index-size.md 272 B
        # db-total-index-size
        
        This command displays the total size of all indexes on the database. It is calculated by taking the number of pages (reported in `relpages`) and multiplying it by the page size (8192 bytes).
        
        ```
            SIZE
          ─────────
            12 MB
        ```
        
      • db-total-table-sizes.md 608 B
        # db-total-table-sizes
        
        This command displays the total size of each table in the database. It is the sum of the values that `pg_table_size()` and `pg_indexes_size()` gives for each table. System tables inside `pg_catalog` and `information_schema` are not included.
        
        ```
                        NAME               │    SIZE
        ───────────────────────────────────┼─────────────
          job_run_details                  │ 395 MB
          slack_msgs                       │ 648 kB
          emails                           │ 640 kB
        ```
        
      • db-traffic-profile.md 1.8 KB
        # db-traffic-profile
        
        This command analyzes table I/O patterns to show read/write activity ratios based on block-level operations. It combines data from PostgreSQL's `pg_stat_user_tables` (for tuple operations) and `pg_statio_user_tables` (for block I/O) to categorize each table's workload profile.
        
        The command classifies tables into categories:
        
        - **Read-Heavy** - Read operations are more than 5x write operations (e.g., 1:10, 1:50)
        - **Write-Heavy** - Write operations are more than 20% of read operations (e.g., 1:2, 1:4, 2:1, 10:1)
        - **Balanced** - Mixed workload where writes are between 20% and 500% of reads
        - **Read-Only** - Only read operations detected
        - **Write-Only** - Only write operations detected
        
        ```
        SCHEMA │ TABLE        │ BLOCKS READ │ WRITE TUPLES │ BLOCKS WRITE │ ACTIVITY RATIO
        ───────┼──────────────┼─────────────┼──────────────┼──────────────┼────────────────────
        public │ user_events  │     450,234 │     9,004,680│       23,450 │ 20:1 (Write-Heavy)
        public │ users        │      89,203 │        12,451│        1,203 │ 7.2:1 (Read-Heavy)
        public │ sessions     │      15,402 │        14,823│        2,341 │ ≈1:1 (Balanced)
        public │ cache_data   │     123,456 │             0│            0 │ Read-Only
        auth   │ audit_logs   │           0 │        98,234│       12,341 │ Write-Only
        ```
        
        **Note:** This command only displays tables that have had both read and write activity. Tables with no I/O operations are not shown. The classification ratio threshold (default: 5:1) determines when a table is considered "heavy" in one direction versus balanced.
        
      • db-unused-indexes.md 923 B
        # db-unused-indexes
        
        This command displays indexes that have < 50 scans recorded against them, and are greater than 5 pages in size, ordered by size relative to the number of index scans. This command is generally useful for discovering indexes that are unused. Indexes can impact write performance, as well as read performance should they occupy space in memory, its a good idea to remove indexes that are not needed or being used.
        
        ```
                TABLE        │                   INDEX                    │ INDEX SIZE │ INDEX SCANS
        ─────────────────────┼────────────────────────────────────────────┼────────────┼──────────────
         public.users        │ user_id_created_at_idx                     │ 97 MB      │           0
        ```
        
      • db-vacuum-stats.md 2.4 KB
        # db-vacuum-stats
        
        This shows you stats about the vacuum activities for each table. Due to Postgres' [MVCC](https://www.postgresql.org/docs/current/mvcc.html) when data is updated or deleted new rows are created and old rows are made invisible and marked as "dead tuples". Usually the [autovaccum](https://supabase.com/docs/guides/platform/database-size#vacuum-operations) process will aysnchronously clean the dead tuples.
        
        The command lists when the last vacuum and last auto vacuum took place, the row count on the table as well as the count of dead rows and whether autovacuum is expected to run or not. If the number of dead rows is much higher than the row count, or if an autovacuum is expected but has not been performed for some time, this can indicate that autovacuum is not able to keep up and that your vacuum settings need to be tweaked or that you require more compute or disk IOPS to allow autovaccum to complete.
        
        ```
                SCHEMA        │              TABLE               │ LAST VACUUM │ LAST AUTO VACUUM │      ROW COUNT       │ DEAD ROW COUNT │ EXPECT AUTOVACUUM?
        ──────────────────────┼──────────────────────────────────┼─────────────┼──────────────────┼──────────────────────┼────────────────┼─────────────────────
         auth                 │ users                            │             │ 2023-06-26 12:34 │               18,030 │              0 │ no
         public               │ profiles                         │             │ 2023-06-26 23:45 │               13,420 │             28 │ no
         public               │ logs                             │             │ 2023-06-26 01:23 │            1,313,033 │      3,318,228 │ yes
         storage              │ objects                          │             │                  │             No stats │              0 │ no
         storage              │ buckets                          │             │                  │             No stats │              0 │ no
         supabase_migrations  │ schema_migrations                │             │                  │             No stats │              0 │ no
        
        ```
        
    • migration
      • list.md 722 B
        ## supabase-migration-list
        
        Lists migration history in both local and remote databases.
        
        Requires your local project to be linked to a remote database by running `supabase link`. For self-hosted databases, you can pass in the connection parameters using `--db-url` flag.
        
        > Note that URL strings must be escaped according to [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986).
        
        Local migrations are stored in `supabase/migrations` directory while remote migrations are tracked in `supabase_migrations.schema_migrations` table. Only the timestamps are compared to identify any differences.
        
        In case of discrepancies between the local and remote migration history, you can resolve them using the `migration repair` command.
        
      • new.md 376 B
        ## supabase-migration-new
        
        Creates a new migration file locally.
        
        A `supabase/migrations` directory will be created if it does not already exists in your current `workdir`. All schema migration files must be created in this directory following the pattern `<timestamp>_<name>.sql`.
        
        Outputs from other commands like `db diff` may be piped to `migration new <name>` via stdin.
        
      • repair.md 2.6 KB
        ## supabase-migration-repair
        
        Repairs the remote migration history table.
        
        Requires your local project to be linked to a remote database by running `supabase link`.
        
        If your local and remote migration history goes out of sync, you can repair the remote history by marking specific migrations as `--status applied` or `--status reverted`. Marking as `reverted` will delete an existing record from the migration history table while marking as `applied` will insert a new record.
        
        For example, your migration history may look like the table below, with missing entries in either local or remote.
        
        ```bash
        $ supabase migration list
                LOCAL      │     REMOTE     │     TIME (UTC)
          ─────────────────┼────────────────┼──────────────────────
                           │ 20230103054303 │ 2023-01-03 05:43:03
           20230103054315  │                │ 2023-01-03 05:43:15
        ```
        
        To reset your migration history to a clean state, first delete your local migration file.
        
        ```bash
        $ rm supabase/migrations/20230103054315_remote_commit.sql
        
        $ supabase migration list
                LOCAL      │     REMOTE     │     TIME (UTC)
          ─────────────────┼────────────────┼──────────────────────
                           │ 20230103054303 │ 2023-01-03 05:43:03
        ```
        
        Then mark the remote migration `20230103054303` as reverted.
        
        ```bash
        $ supabase migration repair 20230103054303 --status reverted
        Connecting to remote database...
        Repaired migration history: [20220810154537] => reverted
        Finished supabase migration repair.
        
        $ supabase migration list
                LOCAL      │     REMOTE     │     TIME (UTC)
          ─────────────────┼────────────────┼──────────────────────
        ```
        
        Now you can run `db pull` again to dump the remote schema as a local migration file.
        
        ```bash
        $ supabase db pull
        Connecting to remote database...
        Schema written to supabase/migrations/20240414044403_remote_schema.sql
        Update remote migration history table? [Y/n]
        Repaired migration history: [20240414044403] => applied
        Finished supabase db pull.
        
        $ supabase migration list
                LOCAL      │     REMOTE     │     TIME (UTC)
          ─────────────────┼────────────────┼──────────────────────
            20240414044403 │ 20240414044403 │ 2024-04-14 04:44:03
        ```
        
      • squash.md 892 B
        ## supabase-migration-squash
        
        Squashes local schema migrations to a single migration file.
        
        The squashed migration is equivalent to a schema only dump of the local database after applying existing migration files. This is especially useful when you want to remove repeated modifications of the same schema from your migration history.
        
        However, one limitation is that data manipulation statements, such as insert, update, or delete, are omitted from the squashed migration. You will have to add them back manually in a new migration file. This includes cron jobs, storage buckets, and any encrypted secrets in vault.
        
        By default, the latest `<timestamp>_<name>.sql` file will be updated to contain the squashed migration. You can override the target version using the `--version <timestamp>` flag.
        
        If your `supabase/migrations` directory is empty, running `supabase squash` will do nothing.
        
    • test
      • db.md 440 B
        # supabase-test-db
        
        Executes pgTAP tests against the local database.
        
        Requires the local development stack to be started by running `supabase start`.
        
        Runs `pg_prove` in a container with unit test files volume mounted from `supabase/tests` directory. The test file can be suffixed by either `.sql` or `.pg` extension.
        
        Since each test is wrapped in its own transaction, it will be individually rolled back regardless of success or failure.
        
    • examples.yaml 16.1 KB
      supabase-init:
        - id: basic-usage
          name: Basic usage
          code: supabase init
          response: Finished supabase init.
        - id: from-workdir
          name: Initialize from an existing directory
          code: supabase init --workdir .
          response: Finished supabase init.
      supabase-login:
        - id: basic-usage
          name: Basic usage
          code: supabase login
          response: |
            You can generate an access token from https://supabase.com/dashboard/account/tokens
            Enter your access token: sbp_****************************************
            Finished supabase login.
      supabase-link:
        - id: basic-usage
          name: Basic usage
          code: supabase link --project-ref ********************
          response: |
            Enter your database password (or leave blank to skip): ********
            Finished supabase link.
        - id: without-password
          name: Link without database password
          code: supabase link --project-ref ******************** <<< ""
          response: |
            Enter your database password (or leave blank to skip):
            Finished supabase link.
        - id: using-alternate-dns
          name: Link using DNS-over-HTTPS resolver
          code: supabase link --project-ref ******************** --dns-resolver https
          response: |
            Enter your database password (or leave blank to skip):
            Finished supabase link.
      supabase-start:
        - id: basic-usage
          name: Basic usage
          code: supabase start
          response: |
            Creating custom roles supabase/roles.sql...
            Applying migration 20220810154536_employee.sql...
            Seeding data supabase/seed.sql...
            Started supabase local development setup.
        - id: without-studio
          name: Start containers without studio and imgproxy
          code: supabase start -x studio,imgproxy
          response: |
            Excluding container: supabase/studio:20221214-4eecc99
            Excluding container: darthsim/imgproxy:v3.8.0
            Started supabase local development setup.
        - id: ignore-health-check
          name: Ignore service health checks
          code: supabase start --ignore-health-check
          response: |
            service not healthy: [supabase_storage_cli]
            Started supabase local development setup.
      supabase-stop:
        - id: basic-usage
          name: Basic usage
          code: supabase stop
          response: |
            Stopped supabase local development setup.
            Local data are backed up to docker volume.
        - id: clean-up
          name: Clean up local data after stopping
          code: supabase stop --no-backup
          response: |
            Stopped supabase local development setup.
      supabase-status:
        - id: basic-usage
          name: Basic usage
          code: supabase status
          response: |2
            supabase local development setup is running.
      
                     API URL: http://127.0.0.1:54321
                 GraphQL URL: http://127.0.0.1:54321/graphql/v1
                      DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
                  Studio URL: http://127.0.0.1:54323
                Inbucket URL: http://127.0.0.1:54324
                  JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
                    anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
            service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
        - id: output-env
          name: Format status as environment variables
          code: supabase status -o env
          response: |
            ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0"
            API_URL="http://127.0.0.1:54321"
            DB_URL="postgresql://postgres:postgres@127.0.0.1:54322/postgres"
            GRAPHQL_URL="http://127.0.0.1:54321/graphql/v1"
            INBUCKET_URL="http://127.0.0.1:54324"
            JWT_SECRET="super-secret-jwt-token-with-at-least-32-characters-long"
            SERVICE_ROLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU"
            STUDIO_URL="http://127.0.0.1:54323"
        - id: output-custom-name
          name: Customize the names of exported variables
          code: supabase status -o env --override-name auth.anon_key=SUPABASE_ANON_KEY --override-name auth.service_role_key=SUPABASE_SERVICE_KEY
          response: |
            Stopped services: [supabase_inbucket_cli supabase_rest_cli supabase_studio_cli]
            SUPABASE_ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0"
            DB_URL="postgresql://postgres:postgres@127.0.0.1:54322/postgres"
            GRAPHQL_URL="http://127.0.0.1:54321/graphql/v1"
            JWT_SECRET="super-secret-jwt-token-with-at-least-32-characters-long"
            SUPABASE_SERVICE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU"
      supabase-migration-list:
        - id: basic-usage
          name: Basic usage
          code: supabase migration list
          response: |2
                  LOCAL      │     REMOTE     │     TIME (UTC)
            ─────────────────┼────────────────┼──────────────────────
                             │ 20230103054303 │ 2023-01-03 05:43:03
                             │ 20230103093141 │ 2023-01-03 09:31:41
              20230222032233 │                │ 2023-02-22 03:22:33
        - id: with-db-url
          name: Connect to self-hosted database
          code: supabase migration list --db-url 'postgres://postgres[:percent_encoded_password]@127.0.0.1[:port]/postgres'
          response: |2
                  LOCAL      │     REMOTE     │     TIME (UTC)
            ─────────────────┼────────────────┼──────────────────────
              20230103054303 │ 20230103054303 │ 2023-01-03 05:43:03
              20230103093141 │ 20230103093141 │ 2023-01-03 09:31:41
      supabase-migration-new:
        - id: basic-usage
          name: Basic usage
          code: supabase migration new schema_test
          response: |
            Created new migration at supabase/migrations/20230306095710_schema_test.sql.
        - id: pipe-stdin
          name: With statements piped from stdin
          code: echo "create schema if not exists test;" | supabase migration new schema_test
          response: |
            Created new migration at supabase/migrations/20230306095710_schema_test.sql.
      supabase-migration-repair:
        - id: basic-usage
          name: Mark a migration as reverted
          code: supabase migration repair 20230103054303 --status reverted
          response: |
            Repaired migration history: 20230103054303 => reverted
        - id: mark-applied
          name: Mark a migration as applied
          code: supabase migration repair 20230222032233 --status applied
          response: |
            Repaired migration history: 20230222032233 => applied
      supabase-db-diff:
        - id: basic-usage
          name: Basic usage
          code: supabase db diff -f my_table
          response: |
            Connecting to local database...
            Creating shadow database...
            Applying migration 20230425064254_remote_commit.sql...
            Diffing schemas: auth,extensions,public,storage
            Finished supabase db diff on branch main.
      
            No schema changes found
        - id: linked-project
          name: Against linked project
          code: supabase db diff -f my_table --linked
          response: |
            Connecting to local database...
            Creating shadow database...
            Diffing schemas: auth,extensions,public,storage
            Finished supabase db diff on branch main.
      
            WARNING: The diff tool is not foolproof, so you may need to manually rearrange and modify the generated migration.
            Run supabase db reset to verify that the new migration does not generate errors.
        - id: specific-schema
          name: For a specific schema
          code: supabase db diff -f my_table --schema auth
          response: |
            Connecting to local database...
            Creating shadow database...
            Diffing schemas: auth
            Finished supabase db diff on branch main.
      
            No schema changes found
      supabase-db-dump:
        - id: basic-usage
          name: Basic usage
          code: supabase db dump -f supabase/schema.sql
          response: |
            Dumping schemas from remote database...
            Dumped schema to supabase/schema.sql.
        - id: role-only
          name: Role only
          code: supabase db dump -f supabase/roles.sql --role-only
          response: |
            Dumping roles from remote database...
            Dumped schema to supabase/roles.sql.
        - id: data-only
          name: Data only
          code: supabase db dump -f supabase/seed.sql --data-only
          response: |
            Dumping data from remote database...
            Dumped schema to supabase/seed.sql.
      supabase-db-lint:
        - id: basic-usage
          name: Basic usage
          code: supabase db lint
          response: |
            Linting schema: public
      
            No schema errors found
        - id: schema-warnings
          name: Warnings for a specific schema
          code: supabase db lint --level warning --schema storage
          response: |
            Linting schema: storage
            [
              {
                "function": "storage.search",
                "issues": [
                  {
                    "level": "warning",
                    "message": "unused variable \"_bucketid\"",
                    "sqlState": "00000"
                  }
                ]
              }
            ]
      supabase-db-pull:
        - id: basic-usage
          name: Basic usage
          code: supabase db pull
          response: |
            Connecting to remote database...
            Schema written to supabase/migrations/20240414044403_remote_schema.sql
            Update remote migration history table? [Y/n]
            Repaired migration history: [20240414044403] => applied
            Finished supabase db pull.
            The auth and storage schemas are excluded. Run supabase db pull --schema auth,storage again to diff them.
        - id: local-studio
          name: Local studio
          code: supabase db pull --local
          response: |
            Connecting to local database...
            Setting up initial schema....
            Creating custom roles supabase/roles.sql...
            Applying migration 20240414044403_remote_schema.sql...
            No schema changes found
            The auth and storage schemas are excluded. Run supabase db pull --schema auth,storage again to diff them.
            exit status 1
        - id: custom-schemas
          name: Custom schemas
          code: supabase db pull --schema auth,storage
          response: |
            Connecting to remote database...
            Setting up initial schema....
            Creating custom roles supabase/roles.sql...
            Applying migration 20240414044403_remote_schema.sql...
            No schema changes found
            Try rerunning the command with --debug to troubleshoot the error.
            exit status 1
      supabase-db-push:
        - id: basic-usage
          name: Basic usage
          code: supabase db push
          response: |
            Linked project is up to date.
        - id: self-hosted
          name: Self hosted
          code: supabase db push --db-url "postgres://user:pass@127.0.0.1:5432/postgres"
          response: |
            Pushing migration 20230410135622_create_employees_table.sql...
            Finished supabase db push.
        - id: dry-run
          name: Dry run
          code: supabase db push --dry-run
          response: |
            DRY RUN: migrations will *not* be pushed to the database.
            Would push migration 20230410135622_create_employees_table.sql...
            Would push migration 20230425064254_my_table.sql...
            Finished supabase db push.
      supabase-db-reset:
        - id: basic-usage
          name: Basic usage
          code: supabase db reset
          response: |
            Resetting database...
            Initializing schema...
            Applying migration 20220810154537_create_employees_table.sql...
            Seeding data supabase/seed.sql...
            Finished supabase db reset on branch main.
      supabase-db-schema-declarative-sync:
        - id: with-pg-delta
          name: Sync declarative schema with pg-delta
          code: |
            # After editing declarative schema files, generate a migration:
            supabase db schema declarative sync --experimental
          response: |
            Creating shadow database...
            Applying declarative schemas via pg-delta...
            Applied 239 statements in 1 round(s).
            Enter a name for this migration (press Enter to keep 'declarative_sync'): add_updated_at
            Created new migration at supabase/migrations/20260317194051_add_updated_at.sql
            Apply this migration to local database? [Y/n]
            Connecting to local database...
            Applying migration 20260317194051_add_updated_at.sql...
            Migration applied successfully.
        - id: generate-first
          name: Generate declarative schema from migrations
          code: |
            supabase db schema declarative sync --experimental
          response: |
            No declarative schema found. Generate a new one ? [Y/n]
            Reset local database to match migrations first? (local data will be lost) [y/N] y
            Resetting database...
            ...
            Declarative schema written to supabase/schemas
            Finished supabase db schema declarative generate.
      supabase-test-db:
        - id: basic-usage
          name: Basic usage
          code: supabase test db
          response: |
            /tmp/supabase/tests/nested/order_test.pg .. ok
            /tmp/supabase/tests/pet_test.sql .......... ok
            All tests successful.
            Files=2, Tests=2,  6 wallclock secs ( 0.03 usr  0.01 sys +  0.05 cusr  0.02 csys =  0.11 CPU)
            Result: PASS
      # TODO: use actual cli response for sso commands
      supabase-sso-show:
        - id: basic-usage
          name: Show information
          code: |-
            supabase sso show 6df4d73f-bf21-405f-a084-b11adf19fea5 \
              --project-ref abcdefghijklmnopqrst
          response: |-
            Information about the identity provider in pretty output.
        - id: metadata-output
          name: Get raw SAML 2.0 Metadata XML
          code: |-
            supabase sso show 6df4d73f-bf21-405f-a084-b11adf19fea5 \
              --project-ref abcdefghijklmnopqrst \
              --metadata
          response: |-
            Raw SAML 2.0 XML assigned to this identity provider. This is the
            version used in the authentication project, and if using a SAML 2.0
            Metadata URL it may change depending on the caching information
            contained within the metadata.
      supabase-sso-update:
        - id: basic-usage
          name: Replace domains
          code: |-
            supabase sso update 6df4d73f-bf21-405f-a084-b11adf19fea5 \
              --project-ref abcdefghijklmnopqrst \
              --domains new-company.com,new-company.net
          response: |-
            Information about the updated provider.
        - id: add-domains
          name: Add an additional domain
          code: |-
            supabase sso update 6df4d73f-bf21-405f-a084-b11adf19fea5 \
              --project-ref abcdefghijklmnopqrst \
              --add-domains company.net
          response: |-
            Information about the updated provider.
        - id: remove-domains
          name: Remove a domain
          code: |-
            supabase sso update 6df4d73f-bf21-405f-a084-b11adf19fea5 \
              --project-ref abcdefghijklmnopqrst \
              --remove-domains company.org
          response: |-
            Information about the updated provider.
      supabase-sso-remove:
        - id: basic-usage
          name: Remove a provider
          code: |-
            supabase sso remove 6df4d73f-bf21-405f-a084-b11adf19fea5 \
              --project-ref abcdefghijklmnopqrst
          response: |-
            Information about the removed identity provider. It's a good idea to
            save this in case you need it later on.
      supabase-sso-add:
        - id: basic-usage
          name: Add with Metadata URL
          code: |-
            supabase sso add \
              --project-ref abcdefgijklmnopqrst \
              --type saml \
              --metadata-url 'https://...' \
              --domains company.com
          response: |-
            Information about the added identity provider. You can use
            company.com as the domain name on the frontend side to initiate a SSO
            request to the identity provider.
        - id: with-xml
          name: Add with Metadata File
          code: |-
            supabase sso add \
              --project-ref abcdefgijklmnopqrst \
              --type saml \
              --metadata-file /path/to/metadata/file.xml \
              --domains company.com
          response: |-
            Information about the added identity provider. You can use
            company.com as the domain name on the frontend side to initiate a SSO
            request to the identity provider.
      supabase-sso-info:
        - id: basic-usage
          name: Show project information
          code: supabase sso info --project-ref abcdefghijklmnopqrst
          response: Information about your project's SAML 2.0 configuration.
      
    • overview.md 5.5 KB
      <p align="center">
        <a href="https://supabase.com">
          <picture>
            <source media="(prefers-color-scheme: dark)" srcset="./docs/assets/supabase-cli-wordmark-dark.svg">
            <img src="./docs/assets/supabase-cli-wordmark-light.svg" alt="Supabase CLI" width="360">
          </picture>
        </a>
      </p>
      
      <p align="center">
        Develop locally and deploy to the Supabase Platform from your terminal.
      </p>
      
      <p align="center">
        <a href="https://www.npmjs.com/package/supabase"><img alt="npm" src="https://img.shields.io/npm/v/supabase?style=flat-square&color=3ECF8E"></a>
        <a href="https://github.com/supabase/cli/actions/workflows/test.yml"><img alt="Build" src="https://img.shields.io/github/actions/workflow/status/supabase/cli/test.yml?branch=develop&label=build&style=flat-square&color=3ECF8E"></a>
        <a href="https://www.npmjs.com/package/supabase"><img alt="License" src="https://img.shields.io/npm/l/supabase.svg?style=flat-square&color=3ECF8E"></a>
        <a href="https://discord.supabase.com"><img alt="Discord" src="https://img.shields.io/discord/839993398554656828?label=discord&style=flat-square&color=3ECF8E"></a>
      </p>
      
      ---
      
      Supabase CLI brings the Supabase Platform to your terminal. Run the full local stack, manage database migrations, deploy Edge Functions, generate types, and automate project workflows.
      
      ## Installation
      
      ```sh
      # YOLO
      curl -fsSL https://raw.githubusercontent.com/supabase/cli/main/install | bash
      
      # npm
      npm install -D supabase                   # or bun/pnpm/yarn add -D supabase
      npm install -D supabase@beta              # beta channel
      
      # macOS and Linux
      brew install supabase/tap/supabase        # always up to date
      brew install supabase                     # official formula, may be delayed
      brew install supabase/tap/supabase-beta   # beta channel
      
      # Windows
      scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
      scoop install supabase
      scoop install supabase-beta               # beta channel
      
      # Linux packages
      # Download .apk, .deb, .rpm, or .pkg.tar.zst from GitHub Releases.
      ```
      
      Linux packages are available from [Releases](https://github.com/supabase/cli/releases). Community-maintained packages are also available through [pkgx](https://pkgx.sh/) and [Nixpkgs](https://nixos.org/).
      
      ## Start Local Development
      
      Create a Supabase workspace and start the local stack:
      
      ```sh
      supabase init
      supabase start
      supabase status
      ```
      
      The local stack includes Postgres, Auth, Realtime, Storage, Edge Functions, and the Supabase APIs.
      
      Start from a template:
      
      ```sh
      supabase bootstrap
      ```
      
      ## Link A Project
      
      Connect your local workspace to a hosted Supabase project:
      
      ```sh
      supabase login
      supabase link
      ```
      
      ## Manage Your Database
      
      Create migrations, compare schemas, and apply changes locally or to your linked project:
      
      ```sh
      supabase migration new create_profiles
      supabase db diff
      supabase db push
      supabase db reset
      ```
      
      ## Deploy Edge Functions
      
      Build, serve, and deploy functions from the same project workspace:
      
      ```sh
      supabase functions new hello-world
      supabase functions serve
      supabase functions deploy hello-world
      ```
      
      ## Generate Types
      
      Generate TypeScript types from your local database or linked project:
      
      ```sh
      supabase gen types --local
      supabase gen types --linked
      ```
      
      ## Reference
      
      Use `--help` on any command to explore flags and examples:
      
      ```sh
      supabase db --help
      supabase functions deploy --help
      ```
      
      - [CLI reference](https://supabase.com/docs/reference/cli/about)
      - [Local development guide](https://supabase.com/docs/guides/local-development)
      - [Supabase docs](https://supabase.com/docs)
      
      ## Developing
      
      This repository is a pnpm monorepo. The published package lives in `apps/cli`.
      
      ```sh
      pnpm install
      pnpm check:all
      
      cd apps/cli
      
      pnpm types:check
      pnpm run test:unit && pnpm run test:integration
      ```
      
      Useful source entry points:
      
      | Path              | Purpose                                |
      | ----------------- | -------------------------------------- |
      | `apps/cli`        | TypeScript/Bun CLI package             |
      | `apps/cli-go`     | Go CLI source used by the legacy shell |
      | `packages/stack`  | Local Supabase stack runtime           |
      | `packages/config` | Config schema and generated types      |
      | `packages/api`    | Typed Supabase Management API client   |
      
      After a fresh clone, install the reference repositories used for agent and developer inspection:
      
      ```sh
      pnpm repos:install
      ```
      
      ## Contributing
      
      We love focused pull requests with a clear problem, a small surface area, and tests that match the user-facing behavior.
      
      Open an issue first and wait for a maintainer to add the `open-for-contribution` label before starting work — external pull requests that don't link a labeled, open issue are closed automatically. See [CONTRIBUTING.md](./CONTRIBUTING.md#contribution-workflow) for the full workflow.
      
      Before opening a PR, run repo-wide quality checks from the repository root,
      then run the relevant package tests from each workspace you touched. For each
      touched TypeScript workspace (or any workspace that declares it), also run its
      `pnpm types:check` script. For example:
      
      ```sh
      # From the repository root:
      pnpm check:all
      
      # From apps/cli (a touched TypeScript workspace):
      cd apps/cli
      pnpm types:check
      pnpm run test:unit && pnpm run test:integration
      
      # Repeat the relevant package tests for every touched workspace; run
      # pnpm types:check there too when that workspace declares the script.
      ```
      
      PR titles must use conventional commits, for example:
      
      ```text
      fix(cli): handle linked projects without cached service versions
      ```
      
      ## License
      
      Supabase CLI packages are released under the MIT license.
      
  • SKILL.md 6.3 KB
    ---
    name: supabase-cli
    description: This skill should be used when user asks to "use supabase CLI", "supabase init", "supabase start", "run migrations", "deploy edge functions", "manage Supabase project", or works with the supabase command-line tool for local development and project management.
    references:
      - commands
      - db
      - migration
      - functions
    license: MIT
    ---
    
    # Supabase CLI Skill
    
    Skill for local development, migrations, edge functions, and project management with the `supabase` CLI. Official docs: https://supabase.com/docs/reference/cli/about
    
    ## Installation
    
    ```bash
    # macOS / Linux (Homebrew)
    brew install supabase/tap/supabase
    
    # npm
    npm install -g supabase
    
    # Windows (Scoop)
    scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
    scoop install supabase
    ```
    
    ## Authentication
    
    ```bash
    # Login with access token from https://supabase.com/dashboard/account/tokens
    supabase login
    
    # Link to a project
    supabase link --project-ref <project-id>
    ```
    
    ## Quick Decision Trees
    
    ### "I need local development"
    
    ```
    Local dev?
    ├─ Initialize project → supabase init
    ├─ Start local stack → supabase start
    │  ├─ Without specific services → supabase start -x studio,imgproxy
    │  └─ Status → supabase status
    ├─ Stop local stack → supabase stop
    │  └─ Clean up data → supabase stop --no-backup
    ├─ View service URLs → supabase status
    └─ Bootstrap from template → supabase bootstrap
    ```
    
    ### "I need database migrations"
    
    ```
    Migrations?
    ├─ Create new migration → supabase migration new <name>
    ├─ Apply pending migrations → supabase migration up
    │  └─ Rollback → supabase migration down
    ├─ Diff local changes → supabase db diff
    │  └─ Save as migration → supabase db diff -f <name>
    ├─ Pull remote schema → supabase db pull
    ├─ Push local migrations → supabase db push
    ├─ Reset local database → supabase db reset
    ├─ List migrations → supabase migration list
    ├─ Squash migrations → supabase migration squash
    ├─ Run arbitrary SQL → supabase db query 'SELECT 1'
    ├─ Run pgTAP tests → supabase test db
    └─ Lint schema → supabase db lint
    ```
    
    ### "I need edge functions"
    
    ```
    Edge Functions?
    ├─ Create new function → supabase functions new <name>
    ├─ Serve locally → supabase functions serve
    │  └─ With env file → supabase functions serve --env-file .env.local
    ├─ Deploy to project → supabase functions deploy <name>
    │  └─ Deploy all → supabase functions deploy
    ├─ Delete function → supabase functions delete <name>
    ├─ List functions → supabase functions list
    └─ Download function → supabase functions download <name>
    ```
    
    ### "I need to manage secrets"
    
    ```
    Secrets?
    ├─ Set secrets → supabase secrets set KEY=value KEY2=value2
    ├─ Set from .env file → supabase secrets set --env-file .env
    ├─ List secrets → supabase secrets list
    └─ Unset secrets → supabase secrets unset KEY KEY2
    ```
    
    ### "I need code generation"
    
    ```
    Code gen?
    ├─ TypeScript types from DB → supabase gen types typescript --project-id <id>
    │  └─ From local DB → supabase gen types typescript --local
    ├─ Signing key → supabase gen signing-key
    └─ Bearer JWT → supabase gen bearer-jwt --project-ref <ref>
    ```
    
    ### "I need to inspect the database"
    
    ```
    Inspect?
    ├─ Database stats → supabase inspect db db-stats
    ├─ Slow queries → supabase inspect db outliers
    ├─ Lock monitoring → supabase inspect db locks / blocking
    ├─ Long running queries → supabase inspect db long-running-queries
    ├─ Index analysis → supabase inspect db index-usage / unused-indexes
    ├─ Table sizes → supabase inspect db table-sizes / table-record-counts
    ├─ Cache hit ratio → supabase inspect db cache-hit
    ├─ Bloat → supabase inspect db bloat
    ├─ Vacuum stats → supabase inspect db vacuum-stats
    └─ Replication slots → supabase inspect db replication-slots
    ```
    
    ### "I need project management"
    
    ```
    Project management?
    ├─ Create project → supabase projects create <name> --org-id <id> --db-password <pw> --region <r>
    ├─ List projects → supabase projects list
    ├─ Delete project → supabase projects delete --project-ref <ref>
    ├─ API keys → supabase projects api-keys --project-ref <ref>
    ├─ Organizations → supabase orgs list / create
    ├─ Custom domains → supabase domains create / get / activate
    ├─ Preview branches → supabase branches create / list / delete
    ├─ Backups (PITR) → supabase backups list / restore
    ├─ SSO management → supabase sso add / list / remove
    └─ Push config → supabase config push
    ```
    
    ## Common Workflows
    
    ### New project setup
    
    ```bash
    supabase init
    supabase start
    # Make schema changes in Supabase Studio (http://127.0.0.1:54323)
    supabase db diff -f initial_schema
    supabase stop
    ```
    
    ### Migration workflow
    
    ```bash
    # Create migration from local changes
    supabase db diff -f add_profiles_table
    
    # Or write SQL directly
    supabase migration new add_profiles_table
    # Edit supabase/migrations/<timestamp>_add_profiles_table.sql
    
    # Test locally
    supabase db reset
    supabase test db
    
    # Deploy to remote
    supabase db push
    ```
    
    ### Edge function development
    
    ```bash
    supabase functions new my-function
    # Edit supabase/functions/my-function/index.ts
    supabase functions serve  # local dev with hot reload
    supabase functions deploy my-function
    ```
    
    ### Generate types after schema change
    
    ```bash
    # From remote project
    supabase gen types typescript --project-id <id> > database.types.ts
    
    # From local running instance
    supabase gen types typescript --local > database.types.ts
    ```
    
    ## Reference Index
    
    | Category | Reference | Description |
    |----------|-----------|-------------|
    | Top-level commands | `references/commands/` | init, start, stop, status, login, link |
    | Database | `references/db/` | diff, dump, lint, pull, push, reset, query |
    | Migrations | `references/migration/` | list, new, repair, squash, up, down |
    | Edge Functions | `references/functions/` | new, serve, deploy, delete |
    | Inspect | `references/inspect/` | 20+ database inspection subcommands |
    | Config | `references/config/` | push config to remote |
    | Domains | `references/domains/` | custom domain management |
    | Tests | `references/test/` | pgTAP database tests |
    | Examples | `references/examples.yaml` | Usage examples for all commands |
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related