Supabase CLI: local Postgres, migrations and Edge Functions from one binary
Supabase CLI. Manage postgres migrations, run Supabase locally, deploy edge functions. Postgres backups. Generating types from your database schema.
At a glance
- What is it?
- The Supabase CLI runs the platform's local stack, tracks schema changes as migration files and deploys Edge Functions. It is built for developers already on Supabase, and its install matrix is broader than its documentation of failure modes.
- Who is it for?
- Adopt it if you already run Supabase and want migrations, local Postgres and Edge Function deploys in one tool. Skip it if you need a vendor-neutral migration runner for a plain Postgres instance, since the workflow assumes a linked Supabase project.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the Supabase CLI actually replaces
Supabase is a hosted platform, and most of its surface area is reachable from a browser dashboard. The CLI exists for the parts of that workflow that do not belong in a browser: schema changes that need to be reviewable as files, a local Postgres and its neighbouring services that need to start and stop on a developer machine, and Edge Functions that need to be built and pushed from a terminal or a CI job.
The README frames it as bringing the platform to your terminal, and lists four jobs: running the full local stack, managing database migrations, deploying Edge Functions, generating types, and automating project workflows. The audience is therefore narrow in a useful way. If you write SQL against a Supabase project and want that SQL to live in git rather than in a dashboard editor, this is the tool. If you run a self-managed Postgres with no Supabase project attached, the CLI's `link` step and hosted-project assumptions become friction rather than help.
How migrations, local services and type generation fit together
The repository is a pnpm monorepo, and the published package lives in `apps/cli`. That package is described as a TypeScript/Bun CLI, and a second directory, `apps/cli-go`, holds Go CLI source used by the CLI. So the shipped binary is not a single-language program: TypeScript and Go both contribute to it. Anyone reading the source to debug a command should know which of the two they are in before they start.
Around those two apps sit shared packages. `packages/stack` is the local Supabase stack runtime, which is what `supabase start` brings up. `packages/config` holds the config schema and generated types, which is what validates the workspace config file. `packages/api` is a typed client for the Supabase Management API, which is what commands like `supabase link` talk to when they act on a hosted project.
The data flow is file-first. `supabase migration new` creates a migration file in the workspace. `supabase db diff` compares schemas. `supabase db push` applies changes to a linked project, and `supabase db reset` rebuilds the local database. Type generation is a read of the same schema: `supabase gen types --local` reads the local database, `--linked` reads the linked project. The migration directory is the source of truth; the hosted database is a target, not the origin.
Installing the Supabase CLI on macOS, Ubuntu and Windows
The README gives several install channels and does not declare one of them canonical. On macOS and Linux, the Homebrew tap is described as always up to date, while the plain `brew install supabase` formula is described as possibly delayed. On Windows, installs go through a Scoop bucket. There are also Linux packages (`.apk`, `.deb`, `.rpm`, `.pkg.tar.zst`) attached to GitHub Releases, plus community-maintained packages via pkgx and Nixpkgs.
The npm route is the one that fits CI, because it pins a version in your lockfile:
npm install -D supabase # or bun/pnpm/yarn add -D supabase
npm install -D supabase@beta # beta channelThere is also a curl installer, which the README labels with the comment `# YOLO`. That label is the project's own, and it is a fair warning: the script is fetched from the repository and executed, so it is the channel with the least pinning.
curl -fsSL https://raw.githubusercontent.com/supabase/cli/main/install | bashFor a first real use, create a workspace and start the local stack. The README shows three commands in sequence, and `supabase status` is the one that tells you whether the stack came up:
supabase init
supabase start
supabase statusAccording to the README, the local stack includes Postgres, Auth, Realtime, Storage, Edge Functions and the Supabase APIs. If you would rather begin from an existing project than an empty workspace, `supabase bootstrap` starts from a template.
Linking a hosted project and the commands that assume it
Several commands are only meaningful once the workspace is connected to a hosted project. The README's sequence is `supabase login` followed by `supabase link`. Until that happens, `--linked` variants have nothing to point at, and `supabase db push` has no destination.
This is the design boundary worth understanding before adopting the tool. The local stack is genuinely local, but the migration and type-generation workflow is built around a Supabase project as the deployment target. If your deployment target is a Postgres instance you manage yourself, you can still use migration files, but the linking and pushing steps do not map onto your infrastructure, and you would be running a tool whose hosted half is inert.
Edge Functions follow the same shape. `supabase functions new hello-world` scaffolds a function, `supabase functions serve` runs it locally, and `supabase functions deploy hello-world` pushes it. Local serving and hosted deployment are two modes of one command family, which is convenient when both ends are Supabase and awkward when only one is.
Where the CLI is the wrong tool
The README documents the happy path thoroughly and the failure paths barely at all. It does not document rollback. There is no described way to undo a `supabase db push` once it has been applied to a linked project, and no documented dry-run flag for that command in the README. Teams that need reversible migrations with a rehearsed down-path should treat that silence as a real gap and verify the behaviour of their pinned version before relying on it.
There is a second, quieter constraint. The repository's contributing section states that external pull requests not linking a labeled, open issue are closed automatically, and that you must wait for a maintainer to add the `open-for-contribution` label before starting work. That is a legitimate policy for a large monorepo, but it means the CLI is not a project where you can land a fix for a bug you hit without first negotiating an issue. If your team's practice is to patch dependencies locally, you are maintaining a fork, not contributing.
Finally, the beta channel is real and active. The most recent releases at the time of writing are `v2.119.0-beta.4`, `v2.119.0-beta.3` and `v2.119.0-beta.2`. The README offers beta installs through npm, the Homebrew tap and Scoop. Choosing a beta channel is a deliberate decision, not a default, and the README does not describe a stability guarantee for it.
Supabase CLI compared with running migrations yourself
The obvious alternative is a standalone migration tool pointed at a Postgres connection string, with no Supabase-specific layer. The difference is not features, it is where the state lives. A generic migration runner assumes you own the database and the connection; the Supabase CLI assumes a workspace directory, a config file validated by `packages/config`, and a linked project reached through the Management API client in `packages/api`.
That extra layer buys you the local stack. `supabase start` brings up Postgres alongside Auth, Realtime, Storage and Edge Functions, which a bare migration runner will not do, and `supabase gen types --local` reads a database that is running on your machine rather than a remote one. If those two things matter to you, the Supabase CLI is doing work that a generic runner cannot. If they do not, you are carrying a hosted-platform client and a local container stack to run SQL files, and a plain runner would be smaller.
Licence, maintenance and the cost of upgrading
The README states that Supabase CLI packages are released under the MIT license, so the permissive terms are stated in the repository. The npm badge in the README points at an npm licence field, and the repository's top-level metadata lists the licence as unknown. Before you depend on the package in a commercial product, read the licence text that ships with the version you install rather than trusting either badge. This is a description of what the repository says, not legal advice.
The last push to the default branch was on 2026-09-28, and the most recent releases are beta builds from the same day. The project is not archived. That does not tell you anything about API stability, and the release list is dominated by betas, so an upgrade is not a formality: command flags and workspace config keys can move between versions. The repository ships a `mise.toml` and `mise.lock` alongside `.bun-version` and `.node-version`, which tells you the maintainers pin their own toolchain. Pinning yours, and reading `supabase db --help` and `supabase functions deploy --help` after each bump, is the cheapest way to catch a changed flag before CI does.
Editorial conclusion
Adopt it if you already run Supabase and want migrations, local Postgres and Edge Function deploys in one tool. Skip it if you need a vendor-neutral migration runner for a plain Postgres instance, since the workflow assumes a linked Supabase project. Before committing, check the MIT licence text shipped in the package, confirm the install channel you picked (npm, brew, scoop or a Linux package) matches your CI runner, and read `supabase db --help` on the version you pin.
Frequently asked questions
How do I login to the Supabase CLI?
Run `supabase login`. The README pairs it with `supabase link` as the two-step sequence that connects your local workspace to a hosted Supabase project.
How do I install the Supabase CLI using Homebrew?
The README lists `brew install supabase/tap/supabase` and describes that tap as always up to date. It also lists `brew install supabase` as the official formula, which it says may be delayed.
How do I update the Supabase CLI?
The README does not document a self-update command. Updates come from whichever channel you installed through: the Homebrew tap is described as always up to date, npm installs move when you change the pinned version, and Linux packages come from GitHub Releases.
How do I install the Supabase CLI on Windows?
The README shows a Scoop bucket: add the bucket, then run `scoop install supabase`. A `supabase-beta` package is also listed for the beta channel.
How do I install the Supabase CLI on Ubuntu or other Linux distributions?
The README points to `.apk`, `.deb`, `.rpm` and `.pkg.tar.zst` packages on GitHub Releases, and notes community-maintained packages through pkgx and Nixpkgs. Homebrew is also listed for Linux.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/supabase-cli)