You are about to get both apps running against your own accounts. This page covers your machine. The following pages explain each provider integration before deployment.
Everything here is reported rather than enforced. Skip Stripe and you still reach a running app, with the checkout route answering 501.
What you need
| Tool | Version | Why |
|---|---|---|
| Node | 22.12.0 or newer | engines in the root package.json |
| pnpm | 11.25.0 | pinned by packageManager |
| git | any |
Do not run this repo through corepack. pnpm refuses to self-switch under it and the packageManager check then fails inside nested turbo tasks. Install pnpm directly and invoke pnpm directly.
The short version
-
Clone and install
git clone git@github.com:<owner>/<repo>.git cd <repo> pnpm installOne lockfile covers all four packages.
@ffd/sharedhas no build step, so there is nothing to compile before the apps can import it. -
Fill in the two env files
cp apps/api/.env.example apps/api/.env cp apps/web/.env.example apps/web/.env.localBoth example files ship with local defaults.
SETUP.mddirects an agent to obtain the account-backed values through each provider's supported tools and write them directly without exposing credentials in chat or terminal output. The steps only you can take, such as choosing an account or copying a dashboard-only key, run in your terminal throughpnpm setup:wizard, which opens each page, takes secrets through hidden input, and checks them against the provider. The provider pages explain those values and the human handoffs. The full list, with which app reads each one, is Environment variables. -
Create the database and run the migrations
pnpm db:migrateThis creates the target database if it is not there, then applies every migration under
packages/shared/drizzle/. It resolves to the development database unless you say otherwise, so migrating production isNODE_ENV=production pnpm db:migrate, typed on purpose.Nothing migrates at boot, so this is a step you run rather than something a deploy does for you.
-
Run both apps
pnpm devTurbo runs
vite devfor the web app on port 3000 andtsx watchfor the api on port 5001. Both reload on save, including changes insidepackages/shared. -
Check that the api agrees with you
curl http://localhost:5001/health{ "status": "ok", "service": "api", "uptimeSeconds": 12, "database": "ffd_dev", "stripeEnv": "test" }databaseis the resolved database name, never the URL, which carries a password.stripeEnvisnullwhen no Stripe key is configured, which is a supported state. Those two fields are the two environment axes, and this endpoint is where you find out they disagree.
Let an agent do it
SETUP.md at the repository root is the agent's end-to-end guide. It covers repository work and external provisioning, using CLIs and APIs first and authenticated browser control where needed. It pauses only for account control, consent, approval, or an ambiguous resource choice, then continues the same sequence.
It is a guide, not a gate. Nothing in it is required, and a buyer who skips a section still reaches a running app.
The two commands that gate a change
pnpm check # Biome, formatting and lint
pnpm typecheck # tsc --noEmit across every package
There is no test suite in this repository and none ships. That is deliberate: your tests are for your product, and a suite covering FFD's own behaviour would be a suite you delete. The two commands above are the whole gate, and a change that has not passed both is not finished.
No CI configuration ships either, so nothing runs them for you until you add a workflow that does.
pnpm check:fix writes the formatting fixes rather than reporting them.
What runs where
| Command | What it does |
|---|---|
pnpm dev |
both apps, watching |
pnpm build |
vite build for web, nothing for the api |
pnpm db:generate |
writes the next migration from the schema diff |
pnpm db:migrate |
creates the database if needed, then migrates |
pnpm check |
Biome |
pnpm typecheck |
tsc --noEmit |
The api has no build step. It runs under tsx in production too, started by pnpm --filter @ffd/api start.
Related
docs/adr/0009-drizzle-v1-on-neon-postgres.md, why nothing migrates at bootdocs/adr/0010-typescript-7-and-biome.md, the toolchain