SupaNet
Building on SupaNet

Deploy

Run SupaNet locally and ship it.

SupaNet is a standard Vite + React app with Supabase Edge Functions. If you have deployed a Supabase project before, none of this will surprise you.

Local development

npm install        # install deps
npm run dev        # Vite dev server on http://localhost:5173
npm run build      # typecheck (tsc -b) + vite build
npm run lint       # eslint
npm run typecheck  # tsc -b --noEmit
npm test           # vitest (frontend unit tests)
npm run test:deno  # deno test (edge-function tests)
npm run gen:types  # regenerate database types from the linked project

Always run npm run build before committing UI or logic changes - it typechecks the whole app. Also run npm test (and npm run test:deno if you changed edge functions). Add or update tests when you add or change logic like parsing, validation, or calculations. Tests for frontend logic live next to the code as src/**/*.test.ts(x); edge-function tests live in supabase/functions/tests/.

Environment and secrets

Two kinds of configuration matter, and keeping them separate is the whole game.

Front end (build-time, public):

VariableNotes
VITE_SUPABASE_URLInlined into the bundle
VITE_SUPABASE_ANON_KEYPublic by design - RLS protects the data

These are read at build time, so they must exist before npm run build.

Edge function secrets (server-side only):

VariableNotes
OPENROUTER_API_KEYRequired. Set with supabase secrets set ..., never commit it
OPENROUTER_MODEL / OPENROUTER_EFFORTOptional overrides
OPENROUTER_SITE_URL / OPENROUTER_APP_NAMEOptional ranking headers

Never put a secret in the front end. Only the anon key belongs there. The OpenRouter key is an edge-function secret and must stay server-side.

Database

The schema lives in supabase/migrations as sequentially-numbered SQL files (0001_init.sql, 0002_skills.sql, …). They are the single source of truth: a fresh project becomes a working backend with one supabase db push, and from then on you never apply migrations by hand.

How new migrations go live

A GitHub Action (.github/workflows/deploy-migrations.yml) runs supabase db push whenever a file under supabase/migrations/ lands on main. The CLI only applies what's pending (the remote tracks applied versions), so merging a PR that adds a new migration file applies exactly that file — no manual step, safe to re-run.

To set this up, add two repository secrets (Settings → Secrets and variables → Actions):

SecretWhat
SUPABASE_ACCESS_TOKENA Supabase personal access token (Dashboard → Account → Access Tokens) — the same one the functions workflow uses.
SUPABASE_DB_PASSWORDYour project's database password (Dashboard → Project Settings → Database). db push connects straight to Postgres, so the token alone isn't enough.

The project ref defaults in the workflow and is overridable with a repository variable SUPABASE_PROJECT_REF.

Adding a migration

# 1. Create the next sequential file (keep numbers unique and contiguous).
#    Write it idempotently where practical (create … if not exists, drop … if exists).
$EDITOR supabase/migrations/0040_my_change.sql

# 2. (Optional) try it locally / against your linked project before merging.
supabase db push

# 3. Refresh the typed client and open a PR.
npm run gen:types

Merging the PR to main triggers the Action, which applies it to the live database.

One rule: every migration filename must have a unique numeric prefix. Two files sharing a number (e.g. two 0032_*.sql) collide — db push derives the version from the prefix and will refuse the push. Always use the next free number.

Fresh project notes

On a brand-new project the storage schema can lag a few seconds. If applying the full migration fails on storage.buckets, apply the core tables first, then the storage section.

If you change the schema locally: refresh the typed client with npm run gen:types and re-check the Supabase security advisors.

Auth redirects

Confirmation and magic-link emails use the Supabase project's Site URL plus the Redirect URLs allowlist. Set these to your deployed origin, or links will point at localhost.

Automatic deployments

Pushing to main updates everything automatically:

  • Tests: a GitHub Action (.github/workflows/test.yml) runs lint, build, frontend tests, and edge-function tests on every PR and every push to main. The feature bot's PRs get the same checks via .github/workflows/claude-feature.yml (GitHub doesn't fire normal PR workflows for bot PRs, so the feature workflow runs them inline).
  • Frontend: Railway rebuilds the app from the latest commit.
  • Edge functions: a GitHub Action redeploys any function that changed.
  • Database migrations: a separate Action applies any new migration files (see Database above).

After the one-time setup of secrets and environment variables, you never run supabase commands by hand.

Workflow

The workflow is trunk-based: run npm run build, commit, and push to main; hosting and migrations pick it up.

Production serve

npm run start  # serve dist/ with SPA fallback

On this page