Every time I start a new Supabase project I end up re-looking-up the same handful of CLI commands. So I keep them in one file. Here is that file, cleaned up — and you can download the raw Markdown at the bottom to drop into your own notes.
Install and verify the CLI
I install the CLI with Homebrew and check the version before doing anything else.
supabase --version
brew upgrade supabase
Then log in and link the local folder to a remote project:
supabase login
supabase projects list
supabase projects create
cd <project-folder>
supabase init # creates supabase/config.toml
supabase link
First migration run (fresh remote)
This is the sequence I follow the first time, against a brand-new remote database (with the PostGIS extension already enabled on the remote):
supabase migration list
supabase migration fetch
supabase db pull --schema auth,storage --debug # pull the remote schema
supabase migration new create_building_tables
# edit the generated create_*_tables.sql
supabase db diff --debug
supabase migration up
supabase db push --include-seed --debug
supabase migration list # local and remote should now be in sync
Iterating on migrations
On every following change the loop is shorter. The key detail is that
supabase migration fetch overwrites local changes, so I only run it when I
want the remote to win.
supabase migration list
supabase migration fetch # overwrites local changes
supabase db diff # what changed locally vs remote
supabase db pull --schema auth,storage --debug
supabase migration new create_*_tables
# edit the migration
supabase migration up # apply the latest migration file
supabase migration list # view migrations still ahead of remote
supabase db push --debug --include-seed
Seeding and importing data
Seeding is just a file: add supabase/seed.sql and it runs on
db push --include-seed (and on db reset).
For importing real data I tried a few paths. Uploading a .csv through the
Table Editor was slow and sometimes incomplete for me. Using a PostgreSQL
client like DBeaver to create the table from SQL and import the CSV was much
faster — a 6-column table with a geometry column and 66 rows imported cleanly.
For bulk loads there is pgloader:
brew update
brew install pgloader
pgloader --version
Backing up a local instance
Stopping with --backup keeps the Docker volumes so nothing is lost:
supabase stop --backup
# inspect the volumes for a given project
docker volume ls --filter label=com.supabase.cli.project=<project-name>
Before any destructive step (like supabase db reset), I dump the local database
so I have a baseline to diff against:
supabase db start
# baseline before cleanup
supabase db dump --local -f baseline_before.sql
# ...after deletions:
# supabase db dump --local -f after.sql
# diff baseline_before.sql after.sql
supabase db reset
A word of caution I keep learning the hard way:
supabase db resetwipes the database. On any instance holding real loaded data, dump a baseline first.
Download
Here is the whole thing as a Markdown file — save it next to your own project notes:
⬇ Download the Supabase CLI cheat sheet (Markdown)