Local Development
This page covers the day-to-day development workflow for working on tripplan.ing locally using the Node runtime.
Setup
npm install
npm run db:migrate:local
make devThe dev server starts at http://localhost:5173 and serves both event sites and the platform UI.
Node runtime behavior
When running locally (no Cloudflare bindings), the app uses the Node runtime:
| Component | Local implementation |
|---|---|
| Database | better-sqlite3 — SQLite file at apps/event-site/data/local.db |
| KV store | In-memory Map — data lost on restart (sessions, OTPs) |
| Blob storage | Filesystem at apps/event-site/data/objects/ |
| Environment vars | .dev.vars file in project root or process.env |
Auto-migration and seeding
The Node runtime automatically:
- Creates the database file if missing
- Applies all pending migrations
- Seeds demo data (a sample event with content) on first run
This means npm run db:migrate:local is optional after the first setup — the dev server handles it. But running it explicitly is useful to verify migration files are correct.
Dev bypass
To skip authentication during development, set ENABLE_DEV_BYPASS=true in .dev.vars:
# .dev.vars
ENABLE_DEV_BYPASS=trueWhen active, the dev bypass:
- Automatically signs you in as
dev@localhost - Grants admin access to all event admin routes
- Grants
super_adminaccess to platform routes - Skips OTP email sending entirely
WARNING
Dev bypass only activates when all four conditions are met:
- No Cloudflare bindings (
platform.envis undefined) - Hostname is
localhostor127.0.0.1 NODE_ENVis notproductionENABLE_DEV_BYPASSis explicitly'true'
Hostname resolution
Locally, the server can't use subdomains for event resolution. Instead, resolveEventByHostname() has a fallback:
- If no hostname match is found and
allowSingleEventFallbackis true (local dev), it returns the first available event - This means
localhost:5173automatically loads whatever event exists in the database
To test multiple events locally, you can add entries to /etc/hosts:
127.0.0.1 reunion.localhost
127.0.0.1 trip.localhostThen access http://reunion.localhost:5173 and http://trip.localhost:5173 (add matching entries to platform_event_domains).
Environment variables
Create a .dev.vars file in the project root for local configuration:
# Required for payments (optional for basic dev)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Required for emails (optional if using dev bypass)
MAILGUN_API_KEY=key-...
MAILGUN_DOMAIN=mg.example.com
# Platform config
PLATFORM_OPERATOR_EMAILS=dev@localhost
PLATFORM_DOMAIN_SUFFIX=localhost
# Dev convenience
ENABLE_DEV_BYPASS=trueWithout Stripe/Mailgun credentials, payments and email features won't work but everything else functions normally.
Quality checks
Run these before pushing:
npm run check # TypeScript + Svelte type checking
npm test # Unit and integration tests
npm run check:boundaries # Monorepo import boundary validationFor schema changes:
npm run db:generate # Generate migration from schema.ts changes
npm run db:migrate:local # Apply locallyFor docs changes:
npm run docs:check # Link validation
npm run docs:build # Full build testTesting Stripe locally
To test payment flows with Stripe:
- Use a Stripe test mode API key in
.dev.vars - Install the Stripe CLI
- Forward webhooks to your local server:
stripe listen --forward-to localhost:5173/api/stripe/webhook- Use the webhook signing secret from the CLI output as
STRIPE_WEBHOOK_SECRET
Debugging tips
- Database inspection: The SQLite file is at
apps/event-site/data/local.db. Use any SQLite client to inspect it directly. - KV is ephemeral: Sessions and OTPs are lost on server restart. If you get logged out, just refresh — dev bypass will recreate the session.
- Blob storage: Uploaded files are in
apps/event-site/data/objects/. You can browse them directly. - Hot reload: Vite hot-reloads client-side changes. Server-side changes require a page refresh.
Related pages
- Quickstart — first-time setup walkthrough
- Code Patterns — coding conventions for the project
- Environment Variables — complete env var reference
- Commands — full command reference