Supabase for database, auth, storage, and realtime features. Use when user mentions "supabase", "supabase auth", "supabase storage", "supabase realtime", "supabase edge functions", "postgres with supabase", "row level security", "RLS", "supabase client", or building apps with Supabase as the backend.
Supabase for database, auth, storage, and realtime features. Use when user mentions "supabase", "supabase auth", "supabase storage", "supabase realtime", "supabase edge functions", "postgres with supabase", "row level security", "RLS", "supabase client", or building apps with Supabase as the backend.
Supabase
Setup
npm install -g supabase # or: brew install supabase/tap/supabase
supabase init # initialize local project
supabase link --project-ref <id> # link to remote project
npm install @supabase/supabase-js # JS/TS client# pip install supabase # Python client
Client initialization:
import { createClient } from'@supabase/supabase-js'const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!)
// Server-side with elevated privileges (bypasses RLS, never expose to client)const supabaseAdmin = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY!)
create table public.posts (
id uuid default gen_random_uuid() primary key,
title text not null,
content text,
user_id uuid references auth.users(id) ondelete cascade not null,
created_at timestamptz default now() not null
);
Migrations and Types
supabase migration new create_posts_table # create migration file
supabase db push # apply migrations to remote
supabase db pull # pull remote schema into migration
supabase db reset # reset local DB, rerun migrations
supabase gen types typescript --linked > src/types/database.ts # generate types
Migration files live in supabase/migrations/ with timestamped filenames.
Row Level Security (RLS)
Always enable RLS on tables exposed to the client. Key functions: auth.uid() returns current user ID, auth.jwt() returns full JWT claims. using controls which existing rows are visible; with check controls which new/modified rows are allowed.
alter table public.posts enable row level security;
create policy "Public read access" on public.posts
forselectusing (true);
create policy "Users can insert own posts" on public.posts
forinsertto authenticated
withcheck (auth.uid() = user_id);
create policy "Users can update own posts" on public.posts
forupdateto authenticated
using (auth.uid() = user_id) withcheck (auth.uid() = user_id);
create policy "Users can delete own posts" on public.posts
fordeleteto authenticated
using (auth.uid() = user_id);
supabase functions new my-function # create
supabase functions serve my-function # local dev
supabase functions deploy my-function # deploy
supabase secrets set MY_API_KEY=value # set secret
supabase secrets list # list secrets
supabase start # start local stack (Postgres, Auth, Storage, Studio)
supabase stop # stop local stack
supabase status # show local URLs and keys
supabase db push # apply migrations to remote
supabase db pull # pull remote schema
supabase db reset # reset local DB
supabase db lint # lint SQL
supabase db diff # diff local vs remote
supabase migration new <name>
supabase migration list
supabase gen types typescript --linked > types/database.ts
supabase functions new <name>
supabase functions serve
supabase functions deploy <name>
supabase secrets set KEY=value
supabase secrets list
Local Development
supabase start launches the full stack. Studio runs at http://localhost:54323. Use local keys in .env.local: