Getting Started
Get a complete ecommerce backend running in your Supabase project.
Getting Started
This guide walks you through setting up supacommerce from scratch — from running the CLI to making your first query.
Prerequisites
- Node.js >= 18.0.0
- A Supabase project (create one here)
- Supabase CLI installed
- pnpm, yarn, bun, or npm
1. Run the CLI
Run the init command in the root of your project:
npx @supacommerce/cli initThe CLI will show you every file it's about to write and ask for confirmation before writing anything. It detects your package manager automatically and prints the correct install commands for your setup.
Options:
npx @supacommerce/cli init --dir ./my-project # target a specific directory
npx @supacommerce/cli init --skip-confirmation # skip the confirmation prompt2. Install dependencies
pnpm add drizzle-orm @supabase/supabase-js @supacommerce/client
pnpm add -D drizzle-kit3. Configure Drizzle
Rename the example config and add your database URL:
mv drizzle.config.example.ts drizzle.config.tsAdd to your .env:
DATABASE_URL="postgresql://postgres:[password]@[host]:5432/postgres"Your DATABASE_URL is in your Supabase project under Settings → Database → Connection string → URI.
4. Recommended package.json scripts
Add these to your package.json before generating migrations:
{
"scripts": {
"drizzle:generate": "drizzle-kit generate",
"drizzle:migrate": "drizzle-kit migrate",
"drizzle:push": "drizzle-kit push"
}
}5. Generate and apply migrations
pnpm drizzle:generate
supabase db pushThis generates SQL from your Drizzle schemas and pushes it to your Supabase project.
6. Apply RLS policies and Postgres functions
Open the Supabase SQL Editor and run these two files in order:
supabase/rls.sql— Row Level Security policiessupabase/functions.sql— Postgres RPC functions
These are not applied by supabase db push — they must be run manually. Both files are fully idempotent and safe to re-run.
7. Set edge function secrets
The edge functions need these secrets set in your Supabase project:
supabase secrets set \
RESEND_API_KEY=re_... \
RESEND_FROM="Your Store <orders@yourdomain.com>" \
EMAIL_FROM="orders@yourdomain.com" \
DASHBOARD_URL="https://your-dashboard-url.com" \
ENVIRONMENT="development"SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, and SUPABASE_ANON_KEY are auto-injected by Supabase — you don't set these manually.
8. Configure store fundamentals
Before creating products or pricing, set these up in order — each one depends on the previous due to FK constraints:
- Currencies — e.g.
USD,ZAR. Thecodefield is the primary key. - Regions — each region references a currency
- Countries — each country belongs to a region
- Tax regions and rates — optional, reference regions
9. Create your first admin user
Run the seed script to create the first admin user:
pnpm seed:adminThis requires these vars in your .env:
VITE_SUPABASE_URL="your_supabase_project_url"
VITE_SUPABASE_SERVICE_ROLE_KEY="your_supabase_service_role_key"
VITE_ADMIN_EMAIL="admin@yourdomain.com"
VITE_ADMIN_PASSWORD="your_secure_password"
VITE_ADMIN_FIRST_NAME="First"
VITE_ADMIN_LAST_NAME="Last"Additional admins are onboarded via the invitation system in the dashboard — not via the seed script.
10. Use the query client
import { createClient as createSupabaseClient } from "@supabase/supabase-js";
import { createClient } from "@supacommerce/client";
const supabase = createSupabaseClient(
process.env.VITE_SUPABASE_URL!,
process.env.VITE_SUPABASE_ANON_KEY!,
);
export const commerce = createClient(supabase);
// List products
const { data, count } = await commerce.catalog.listProducts({ limit: 20 });
// Get or create a cart
const cart = await commerce.cart.getOrCreate();
// Add an item
await commerce.cart.addItem(cart.id, { variantId: "...", quantity: 1 });Anonymous / guest carts
Carts require a Supabase auth user. For unauthenticated customers, use anonymous auth:
await supabase.auth.signInAnonymously();
// Cart persists across sessions.
// When the user creates a full account, Supabase upgrades the anonymous
// user automatically and the cart is preserved.RLS works identically for anonymous and authenticated users — no special handling needed.
Resetting your database
Two SQL utility scripts are included for development:
supabase/nuke-dbs.sql — truncates all tables, preserving schema and policies. Use this to clear all data without dropping anything.
supabase/drop-dbs.sql — drops all tables and enums entirely. Use this when you need a completely clean slate before re-running migrations.
Run either file in the Supabase SQL Editor.