Two commands, and nothing to install first beyond Node and pnpm.
pnpm install && pnpm run setup
pnpm dev
setup copies .env.example to .env, generates BETTER_AUTH_SECRET, runs the
migrations and seeds a demo user. Then pnpm dev serves the app on
localhost:3000.
Why there is no database step
The kit runs PGlite — Postgres compiled to WebAssembly — in the same process
as the dev server, with its data under .pglite/dev. That is why there is no
Docker step and no connection string to find. It is real Postgres, so the SQL,
the migrations and the extensions you use in development are the ones you use in
production.
Set DATABASE_URL and the kit switches to a real Postgres server instead. That
one variable is the whole switch — see Deploying.
What is fake until you say otherwise
Every provider has a built-in fake, chosen by the absence of a key:
- payments run an in-memory Stripe with deterministic ids
- email is written to
.mail/as JSON instead of being sent - the AI model and the embedder are deterministic stubs
- file uploads land in
.storage/and are still presigned
Adding a key swaps the fake for the real thing with no code change. pnpm run doctor prints which of them are real right now.
Knowing when you are done
Every feature carries an acceptance spec — a machine-checkable definition of done that runs against a real database and a real server.
pnpm verify # types, lint, tests, contrast, code health
pnpm accept:all # every feature's acceptance spec
A feature is finished when pnpm accept <feature> is green, and not before.