Project Setup and the Supabase CLI
The idea in one sentence
Section titled “The idea in one sentence”A Supabase project starts as a hosted Postgres instance with two API keys of very different trust levels, and the Supabase CLI is what lets you link a local folder to it and run the entire stack on your own machine with Docker.
Creating a project and its two keys
Section titled “Creating a project and its two keys”You create a new hosted project from the Supabase dashboard, or the shortcut database.new. Behind the scenes this provisions a dedicated Postgres instance, an API URL, and two API keys:
anonkey — public, safe to ship in client-side code (a browser bundle, a mobile app). Requests using this key are subject to Row Level Security.service_rolekey — secret, full-access, bypasses Row Level Security entirely. It is meant only for trusted server-side code.
// Server-side only — e.g. an API route, a cron job, an Edge Function.// process.env.SUPABASE_SERVICE_ROLE_KEY must never be bundled into client code.import { createClient } from '@supabase/supabase-js';
const supabaseAdmin = createClient( process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY!);The Supabase CLI
Section titled “The Supabase CLI”The CLI is how you manage a project as code instead of only through the dashboard:
# Scaffold a local supabase/ config directory in your projectnpx supabase init
# Authenticate the CLI with your Supabase accountsupabase login
# Connect this local project folder to a specific hosted projectsupabase link --project-ref <project-ref>supabase link is what tells your local supabase/ folder which hosted project it corresponds to — every later db push or db diff targets that linked project.
Local development with supabase start
Section titled “Local development with supabase start”supabase startThis spins up the entire Supabase stack locally via Docker — Postgres, Studio, Auth, Storage, Realtime, and the rest, all running as containers on your machine. That means you can develop and test your schema, your RLS policies, and your client code completely offline, with no risk to your hosted project, before ever running supabase db push against it.
flowchart LR
subgraph local["Local machine (supabase start)"]
lpg[("Postgres")]
lstudio["Studio"]
lauth["Auth"]
lstorage["Storage"]
end
subgraph hosted["Hosted project"]
hpg[("Postgres")]
hapi["API URL + anon/service_role keys"]
end
local -- "supabase link --project-ref" --> hosted
local -- "supabase db push" --> hosted