📖 Guide
Supabase — Complete Reference
Complete Supabase cheat sheet — auth, database, realtime, storage, and edge functions.
68 commands across 9 categories
CLIAuthenticationDatabase QueriesRealtimeStorageEdge FunctionsRow Level SecurityMigrationsCommon Patterns
CLI
| Command | Description |
|---|---|
npx supabase init | Initialize Supabase in your project |
npx supabase start | Start local Supabase stack (requires Docker) |
npx supabase stop | Stop the local Supabase stack |
npx supabase status | Show status of local Supabase services and URLs |
npx supabase db reset | Reset local database (reapply migrations and seed) |
npx supabase link --project-ref <ref> | Link to a remote Supabase project |
npx supabase db push | Push local migrations to the remote database |
npx supabase gen types typescript --local | Generate TypeScript types from the local database schema |
Authentication
| Command | Description |
|---|---|
supabase.auth.signUp({ email: 'a@b.com', password: 'secret' }) | Sign up a new user with email/password |
supabase.auth.signInWithPassword({ email: 'a@b.com', password: 'secret' }) | Sign in with email and password |
supabase.auth.signInWithOAuth({ provider: 'google' }) | Sign in with OAuth provider (google, github, discord, etc.) |
supabase.auth.signInWithOtp({ email: 'a@b.com' }) | Send a magic link or OTP to email |
supabase.auth.signOut() | Sign the current user out |
supabase.auth.getUser() | Get the currently authenticated user (server-side verified) |
supabase.auth.getSession() | Get the current session (includes access token) |
supabase.auth.onAuthStateChange((event, session) => { ... }) | Listen for auth state changes (sign in, sign out, token refresh) |
Database Queries
| Command | Description |
|---|---|
supabase.from('posts').select('*') | Select all columns from a table |
supabase.from('posts').select('id, title, author:users(name)') | Select specific columns with a relation join |
supabase.from('posts').insert({ title: 'Hello', body: 'World' }) | Insert a new row |
supabase.from('posts').insert([row1, row2]) | Insert multiple rows at once |
supabase.from('posts').update({ title: 'Updated' }).eq('id', 1) | Update rows matching a condition |
supabase.from('posts').upsert({ id: 1, title: 'Upserted' }) | Insert or update based on primary key |
supabase.from('posts').delete().eq('id', 1) | Delete rows matching a condition |
supabase.from('posts').select('*').single() | Expect exactly one row (throws if 0 or >1) |
Realtime
| Command | Description |
|---|---|
supabase.channel('room1').on('broadcast', { event: 'cursor' }, (payload) => { ... }).subscribe() | Subscribe to broadcast messages on a channel |
channel.send({ type: 'broadcast', event: 'cursor', payload: { x: 100 } }) | Send a broadcast message to a channel |
supabase.channel('room1').on('presence', { event: 'sync' }, () => { ... }).subscribe() | Track user presence on a channel |
channel.track({ user_id: '123', online_at: new Date() }) | Send presence state for the current user |
supabase.channel('db-changes').on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'posts' }, (payload) => { ... }).subscribe() | Listen for database INSERT events in realtime |
supabase.channel('db-changes').on('postgres_changes', { event: '*', schema: 'public', table: 'posts' }, callback).subscribe() | Listen for all change events (INSERT, UPDATE, DELETE) |
supabase.removeChannel(channel) | Unsubscribe and remove a channel |
Storage
| Command | Description |
|---|---|
supabase.storage.createBucket('avatars', { public: true }) | Create a public storage bucket |
supabase.storage.from('avatars').upload('path/photo.png', file) | Upload a file to a bucket |
supabase.storage.from('avatars').upload('path/photo.png', file, { upsert: true }) | Upload and overwrite if exists |
supabase.storage.from('avatars').download('path/photo.png') | Download a file as a Blob |
supabase.storage.from('avatars').getPublicUrl('path/photo.png') | Get the public URL for a file |
supabase.storage.from('avatars').createSignedUrl('path/photo.png', 3600) | Create a signed URL valid for N seconds |
supabase.storage.from('avatars').remove(['path/photo.png']) | Delete files from a bucket |
supabase.storage.from('avatars').list('folder/', { limit: 100 }) | List files in a folder |
Edge Functions
| Command | Description |
|---|---|
npx supabase functions new my-function | Create a new edge function |
npx supabase functions serve | Serve edge functions locally for development |
npx supabase functions deploy my-function | Deploy an edge function to production |
supabase.functions.invoke('my-function', { body: { name: 'World' } }) | Invoke an edge function from the client |
Deno.serve(async (req) => {
return new Response('Hello')
}) | Basic edge function handler (Deno runtime) |
npx supabase secrets set MY_SECRET=value | Set environment variables for edge functions |
Row Level Security
| Command | Description |
|---|---|
ALTER TABLE posts ENABLE ROW LEVEL SECURITY; | Enable RLS on a table (required for policies) |
CREATE POLICY "Users can read all posts"
ON posts FOR SELECT
USING (true); | Allow all users to read (SELECT) posts |
CREATE POLICY "Users can insert own posts"
ON posts FOR INSERT
WITH CHECK (auth.uid() = user_id); | Allow users to insert only their own posts |
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id); | Allow users to update only their own posts |
CREATE POLICY "Users can delete own posts"
ON posts FOR DELETE
USING (auth.uid() = user_id); | Allow users to delete only their own posts |
auth.uid() | Returns the authenticated user's UUID (use in RLS policies) |
auth.jwt() ->> 'role' | Access JWT claims in RLS policies (e.g., custom role) |
Migrations
| Command | Description |
|---|---|
npx supabase migration new create_posts | Create a new empty migration file |
npx supabase db push | Push all local migrations to the remote database |
npx supabase db pull | Pull remote schema changes as a migration |
npx supabase db diff --use-migra -f add_column | Generate a migration from schema differences |
npx supabase migration list | List all migrations and their status |
npx supabase db reset | Reset local database and rerun all migrations |
Common Patterns
| Command | Description |
|---|---|
.eq('column', 'value') | Filter: equals |
.neq('column', 'value') | Filter: not equals |
.gt('age', 18) | Filter: greater than (also: gte, lt, lte) |
.like('name', '%john%') | Filter: SQL LIKE pattern matching |
.ilike('name', '%john%') | Filter: case-insensitive LIKE |
.in('status', ['active', 'pending']) | Filter: value in array |
.order('created_at', { ascending: false }) | Order results by column |
.range(0, 9) | Paginate results (offset-based, 0-indexed, inclusive) |
.select('*', { count: 'exact' }) | Include total row count in response |
supabase.rpc('my_function', { param: 'value' }) | Call a Postgres function via RPC |
📖 Free, searchable command reference. Bookmark this page for quick access.