Install and run locally
Prerequisites, the first install, and the commands that start Supabase and the web app on your machine.
Prerequisites
| Tool | Version | Why |
|---|---|---|
| Node.js | 22.13.0 or later | engines.node in the root package.json. pnpm 11 does not run on older versions. |
| pnpm | 11.21.0 | Pinned by packageManager in the root package.json |
| Docker, or OrbStack on macOS | Current | The local Supabase stack runs in containers |
| Git | Current |
The phone app has its own requirements (Xcode for iOS on a Mac, Android Studio for Android). See docs/native/running-locally.mdoc.
1. Install dependencies
From the repository root:
pnpm install
Only the dependencies listed under allowBuilds in pnpm-workspace.yaml may run install scripts. If every pnpm command starts failing with ERR_PNPM_IGNORED_BUILDS after you add a dependency, see known issue 17 in docs/troubleshooting/agent-known-issues.md.
2. Start Supabase
Start Docker first, then:
pnpm supabase:web:start
The first start downloads the Supabase images, then applies the migrations in apps/web/supabase/migrations and the seed in apps/web/supabase/seed.sql. Ports come from apps/web/supabase/config.toml:
| Service | Address |
|---|---|
| API | http://127.0.0.1:54321 |
| Postgres | port 54322 |
| Supabase Studio | http://localhost:54323 |
| Mailpit (local inbox) | http://localhost:54324 |
3. Start the web app
pnpm dev
This runs every workspace that has a dev script: the web app at http://localhost:3000 and the developer tool (apps/dev-tool) at http://localhost:3010. apps/web/.env.development already points the web app at the local Supabase stack and the local mail server, so you need no keys to run it locally.
4. Sign in with a seeded user
seed.sql creates test users. Their password is testingpassword, which the end-to-end tests also use.
| Use | |
|---|---|
test@shipanysaas.com | Owner of the seeded Acme team. Also has the super-admin role, but no MFA factor |
owner@shipanysaas.com, member@shipanysaas.com, custom@shipanysaas.com | Users the database tests sign in as |
super-admin@shipanysaas.com | Super admin. Needs a two-step code: the TOTP secret is in the mfa_factors insert in seed.sql |
The seed is for your machine only. Never push it to a hosted project (supabase db push --include-seed): it contains a published super-admin login.
Every email the app sends locally, including Supabase Auth emails, lands in Mailpit at http://localhost:54324.
5. Billing webhooks (optional)
To test Stripe checkout locally:
pnpm stripe:listen
This runs the Stripe CLI in Docker (stripe/stripe-cli) and forwards events to http://host.docker.internal:3000/api/billing/webhook. It reuses your Stripe CLI login from ~/.config/stripe. Put the whsec_... secret it prints, and your test-mode STRIPE_SECRET_KEY, in apps/web/.env.local. That file is ignored by Git.
Stop and reset
pnpm supabase:web:stop # stop the containers pnpm supabase:web:reset # re-apply migrations and the seed; wipes local data
After you edit a file in apps/web/.env*, restart pnpm dev. The running server keeps the old values (known issue 14 in docs/troubleshooting/agent-known-issues.md).
The phone app
pnpm start:native # Expo dev server pnpm ios:native # build and run on iOS (needs Xcode) pnpm android:native # build and run on Android
Setup, device networking and store builds are covered in docs/native/.