Skip to content

Supabase Setup Guide

Supabase Setup Guide

This guide covers everything needed to connect Surfc to Supabase for cross-device sync, including the migration workflow for keeping schema in sync across environments.


Prerequisites: Supabase CLI

Surfc uses the Supabase CLI to manage and scaffold migration files. Install it once as a project devDependency (already listed in package.json):

Terminal window
npm install

The CLI is then available via npm scripts (e.g. npm run migrate:new). To confirm it is installed:

Terminal window
npx supabase --version

1. Create a Supabase project

  1. Go to supabase.com and sign in
  2. Click New project
  3. Choose a name (e.g. surfc), set a database password, and select a region
  4. Wait ~2 minutes for provisioning

2. Get your credentials

In your project dashboard, go to Settings → API:

ValueWhere to find it.env variable
Project URLSettings → API → Project URLVITE_SUPABASE_URL
Anon / public keySettings → API → anon keyVITE_SUPABASE_ANON_KEY
Service role keySettings → API → service_role keySUPABASE_SERVICE_ROLE_KEY (see below)
DB connection stringSettings → Database → Connection string (Session Mode)DATABASE_URL (see below)

Copy .env.example to .env and fill in VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY.

Never use the service_role key in the app — it bypasses row-level security.


3. Developer tooling variables (local only)

Two additional variables are required to run npm run check:schema. Add them to your local .env — they are intentionally absent from .env.example because they carry elevated database privileges.

# .env additions — never commit
SUPABASE_SERVICE_ROLE_KEY=eyJ... # Settings → API → service_role key
DATABASE_URL=postgresql://postgres.your-project:password@aws-0-region.pooler.supabase.com:5432/postgres

For DATABASE_URL, use the Session Mode pooler (port 5432) from: Settings → Database → Connection string → Session mode

These variables are consumed only by scripts/check-schema.js (a Node.js tool, never bundled into the browser app).


4. Apply migrations

Schema changes are managed as versioned SQL files in supabase/migrations/. Apply them in order by pasting each file into the Supabase SQL Editor (Dashboard → SQL Editor → New query → paste → Run):

FileWhat it does
0001_initial_schema.sqlCreates tables, RLS policies, storage bucket
0002_notes_add_source.sqlAdds source column to notes
0003_notes_add_source_ingest.sqlAdds source_id, source_meta, and index

All migration files are idempotent (IF NOT EXISTS guards) — safe to re-run against an existing database.


5. Verify the schema

After applying migrations, run the drift check to confirm the live schema matches the contract the app depends on:

Terminal window
npm run check:schema

A passing run prints:

[check-schema] ✓ All 30 checks passed — schema matches contract.

A failing run names every issue:

[check-schema] 28 passed, 2 failed:
✗ [column] column "source_id" missing from table "notes"
✗ [column] column "source_meta" missing from table "notes"
[check-schema] Apply pending migrations via the Supabase SQL editor, then re-run.

6. Configure email auth

By default Supabase requires email confirmation before sign-in. For development you may want to disable this:

  1. Go to Authentication → Providers → Email
  2. Toggle off Confirm email

7. Add environment variables to Netlify

If deploying via Netlify:

  1. Go to Site configuration → Environment variables
  2. Add VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY
  3. Trigger a new deploy

DATABASE_URL and SUPABASE_SERVICE_ROLE_KEY are developer tools only — do NOT add them to Netlify.


8. Verify the full setup

  1. Run npm run dev locally
  2. The app should show a sign-in screen
  3. Create an account and sign in
  4. Add a note — check the Supabase dashboard under Table Editor → notes to confirm it appears

Adding new migrations

When the schema needs to change:

  1. Create a new migration file using the CLI:

    Terminal window
    npm run migrate:new -- describe_the_change

    This creates a timestamped file in supabase/migrations/.

  2. Write the SQL (use IF NOT EXISTS / IF EXISTS guards to keep it idempotent).

  3. Update scripts/schema-contract.js if you are adding a required table, column, policy, or resource that the app depends on.

  4. In your PR description, call out:

    • The migration filename
    • What it changes
    • The steps to apply it (paste into SQL editor, then npm run check:schema)
  5. After merging, apply the migration to the production Supabase project before deploying the client that depends on it.


Migration notification hook

To be reminded whenever you stage a migration file, activate the project’s git hook:

Terminal window
npm run setup-hooks

This runs once per clone and prints a reminder in the terminal any time a migration is committed.


Free tier limits (as of 2026)

ResourceFree limitSurfc usage
Database size500 MBVery low — text only
Storage1 GBModerate — one image per note
Auth usersUnlimited
API requestsUnlimited

Storage is the main constraint if you photograph many passages. Each compressed note image is typically 200–400 KB, so the 1 GB limit accommodates roughly 2,500–5,000 images.