53 views
Supabase Local Development
This post is summary of how to setup a local development environment for Supabase. There's a strong emphasis on the database because that's usually the tricky part. I like to use this post as a cheat sheet for my own reference.
Running Supabase locally
The Supabase command line interface (CLI) lets you to run the entire stack locally. Let's start by creating a new project:
npx supabase init
This creates a supabase
folder with a .temp
folder and the config.toml
file.
The former has unimportant stuff, the latter has important configuration stuff.
To start the Supabase stack, you must launch Docker Desktop and run the command below. This takes time the first time because the Docker images need to be downloaded.
npx supabase start
Congrats! You've just created a local development environment for Supabase.
Next, to check the status and get the local development URLs, run:
npx supabase status
To stop the stack, exchange <project_name>
with the actual name of your project and run:
npx supabase stop --project-id <project_name>
Using Google auth locally
While testing, it helps to setup Auth to work locally. Here's a quick guide to setup Google Auth on a local Supabase instance. Setting up other Auth providers is similar.
Google Developer Console
Begin by creating new credentials for an OAuth 2.0 client ID in the APIs and services section of the Google Developer Console. Start the setup by clicking on the "Create credentials" button.
During the setup, add the following redirect URI:
http://localhost:54321/auth/v1/callback
That's the standard path for the callback. For testing purposes, the redirect points to your local Supabase instance (see Redirect URI). After walking though the setup, you will get a client ID and client secret (see Client ID and secret):
Supabase configuration
Back in the project, open the config.toml
file and add the following to the auth_providers
section:
[auth.external.google]
enabled = true
client_id = "env(GOOGLE_CLIENT_ID)"
secret = "env(GOOGLE_CLIENT_SECRET)"
redirect_uri = "http://127.0.0.1:54321/auth/v1/callback"
url = ""
skip_nonce_check = false
Now, create an .env
file in the root of the project and add the id and secret you got from the Google Developer Console:
GOOGLE_CLIENT_ID="insert_id_here"
GOOGLE_CLIENT_SECRET="insert_secret_here"
For these changes to take effect, you need to stop and start Supabase. More details on local auth can be found in the Supabase documentation.
NextJS components
The Google auth flow works as follows:
- User clicks login button which opens Google auth page
- After successful login user is redirected to Supabase callback:
localhost:54321/auth/v1/callback
- Supabase processes OAuth and redirects to the callback in the NextJS app
- App callback exchanges code for session and redirects to final destination
Here's an example of a Google login button component that uses the Supabase client to sign-in with Google.
// .../components/google-login.tsx
'use client';
import { FcGoogle } from "react-icons/fc";
import { Button } from "@/components/ui/button";
import { createClient } from "@/utils/supabase/client";
import { AppRoutes } from "@/routes";
export const GoogleLogin = () => {
const supabase = createClient();
const onClick = async () => {
supabase.auth.signInWithOAuth({
provider: "google",
options: {
redirectTo: `${origin}/api/auth/callback?redirect=${encodeURIComponent("/dashboard")}`,
},
});
}
return (
<div className="flex items-center w-full gap-x-2">
<Button
size="lg"
className="w-full"
variant="outline"
onClick={onClick}
>
<FcGoogle className="h-5 w-5" />
</Button>
</div>
)
}
Local database migrations
Migrations let us version control changes — such as creating tables, adding columns, or inserting data — to a database. This ensures that database changes are consistently applied across different environments.
Create a new migration
Migrations are .sql
files stored in the supabase/migrations
folder.
To create a new and empty migration file, run:
npx supabase migration new example_migration
This will create a new file with the name structure <timestamp>_example_migration.sql
inside the supabase/migrations
folder.
You can add any SQL statements to the migration file, such as:
-- Example migration file
create table if not exists example_table (
id uuid default gen_random_uuid() primary key,
message text not null
);
insert into example_table (message) values ('Hello, world!');
This migration file creates the example_table
with an id
and a message
column and inserts a row with data into the table.
Apply a migration locally
By applying a migration, the SQL code in the migration files gets applied to the database on the local Supabase instance. To apply a migration such as the one above, run:
npx supabase migration up
Afterwards, you'll see the changes applied in the Supabase studio?Similar to the dashboard on the Supabase platform but tailored to local development. As you can see from the studio snapshot below, the table and row have been created from the content of the migration file:
Pull local database changes
Sometimes making changes via the studio (running locally) is more convenient then writing SQL code. To pull these changes back into our editor, we can write the new changes into a migration file using:
npx supabase db diff -f new_changes_migration
This creates a new migration file in supabase/migrations
with the difference (aka. the diff) between the files stored in the migrations
folder and the local database that we edited using the studio.
Here's an example of a migration file that contains the diff after adding a column to the example_table
table in the Supabase studio:
-- Example 'diff'
alter table "public"."example_table" add column "user" text;
Dump the local database
A dump let's us get the schema and data from the database. Here's how to dump the local database schema, data and a specific schema:
npx supabase db dump --local -f supabase/dump_schema.sql
Reset the local database
A reset recreates the local Postgres container and applies all local migrations found in supabase/migrations
directory
npx supabase db reset
If test data is defined in supabase/seed.sql
, it will be seeded after the migrations are run.
Remote database migrations
Linking to a hosted project
Applying database migrations to the Supabase platform requires a link between your local project and the Supabase platform.
To create the link, insert your project_id
(aka. project ref.) into:
npx supabase link --project-ref <project_id>
You'll be prompted for the database password which can be found in Settings / Database
.
To remove the link, run:
npx supabase unlink
Apply a remote migration
Applying a migration to a linked remote database is done using:
supabase db push
Once pushed, you can check that the migration version is up to date for the local and remote database by running:
supabase migration list
Dump the remote database
The CLI commands are similar to the ones we used for the local database except that we don't use the --local
flag:
npx supabase db dump -f supabase/dump_schema.sql
Reset the remote database
To reset the remote database using the migrations in your supabase/migrations
folder, include the --linked
flag:
npx supabase db reset --linked
Careful with this one. Make a data and schema backup before running this command.
Generating TypeScript Types
To generate TypeScript types for the local or remote database, run:
npx supabase gen types --local --lang=typescript > ./types.ts
More information on how to use the generated types file can be found in this YouTube video.