Contributing

How to run the code, and what a change has to clear before it is merged.

Getting started

nvm use          # or otherwise match .nvmrc
npm install
npm run dev

Use the Node version in .nvmrc; CI pins the same one. It is not cosmetic — npm versions disagree about which transitive optional/wasm packages belong in package-lock.json, so an npm install on a different Node writes a lockfile that your machine accepts and CI rejects with Missing: ... from lock file. If you bump .nvmrc, bump NODE_VERSION in .github/workflows/ci.yml too and regenerate the lockfile with the matching npm.

The repo ships with a demo journal at /example, rebuilt with npm run demo:build, so the app works end to end with no real trip data. Real configuration lives in site/config.json, read by lib/config.ts — don't put personal data or secrets in code; see docs/plans/INDEX.md for the ground rules the codebase follows (feature flags default off, secrets stay in the environment, and so on).

Before you open a PR

Run all four of these — CI runs the same checks:

npm run build          # first — it writes .next/types, which tsc reads
npx tsc --noEmit
npx eslint .
npx vitest run

The build goes first because Next writes the typed-route definitions in .next/types while it builds, and PageProps, LayoutProps and RouteContext resolve against them. Run tsc on a checkout that has never been built and it reports errors in every route file, none of which are yours.

A PR that fails any of these won't be merged as-is. If a check is failing for a reason unrelated to your change, say so in the PR description rather than silently working around it.

The whole file, and the licence terms, are in the repository.