Deploying

Set DATABASE_URL to a real Postgres server and run the migrations against it. Everything else is optional and additive: each provider key you set swaps a built-in fake for the real service with no code change. The application builds and boots with none of them, so the first deploy can be a working site that simply has not been connected to Stripe or Resend yet.

The only required change is the database.

1. Point at a real Postgres

Embedded PGlite is a development convenience; it is not what you deploy. Set DATABASE_URL and the kit uses the pg driver instead, with no other change:

DATABASE_URL=postgres://user:password@host:5432/dbname

Then run the migrations against it:

DATABASE_URL=… pnpm db:migrate

Any managed Postgres works. guide/keys/neon.md walks through one.

2. Set the keys you actually want

None of these are required to boot. Each one swaps a fake for the real service:

| Key | What it turns on | |---|---| | STRIPE_SECRET_KEY | real payments (see the Stripe pages) | | RESEND_API_KEY | real email delivery | | ANTHROPIC_API_KEY / OPENAI_API_KEY | real model responses | | S3_BUCKET and its credentials | real object storage | | SENTRY_DSN | error monitoring |

pnpm run doctor tells you which are live and which are still fake.

3. After the first deploy

  • pnpm seo:check — every registered page is reachable, canonical and in the sitemap.
  • Check the webhook endpoint if you took the Stripe key: a missing event subscription breaks billing silently.
  • Read guide/STRIPE-ACCOUNT.md before taking real money.

What does not change

The migrations, the schema and the queries are identical in both modes, because both are Postgres. That is the point of using PGlite rather than SQLite for local development: there is no dialect gap to discover on deploy day.

← All Documentation