Skip to main content
Just want the app running? Run the app locally is the two-command version. This page is the reference for everything else.

Requirements

Scripts

CI runs lint, type-check, test:mock, build and worker:build. Run all five before opening a pull request.

Environment variables

pnpm dev:mock sets everything it needs inline, so copying .env.example is not required for local development.
Base URLs are resolved once in src/config/config.ts: server-side code uses INTERNAL_SERVER_API_URL (falling back to the public one), browser code uses NEXT_PUBLIC_API_URL. Trailing slashes are stripped, and a missing value logs a warning rather than throwing.

Project layout

Tooling notes

@/* maps to ./src/*. There are no other path aliases.
Import order is enforced by Biome’s organizeImports assist. pnpm lint fails on unsorted imports, pnpm lint:write fixes them.
Tailwind is configured in CSS, in src/app/globals.css: an @theme inline block maps design tokens to utilities, and :root holds the raw values, including the brand ramp --ost-blue-one--ost-blue-four.To add or change a design token, edit globals.css. Don’t create a tailwind.config.js. It would be ignored.
Configured in components.json: new-york style, neutral base colour, CSS variables, RSC enabled. Components are aliased to @/shared/components/ui, utilities to @/shared/lib/utils.
Generated files land in src/shared/components/ui/.
  • noEnum: TypeScript enum is banned. Use a union type or a const object.
  • 80-column lines, 2-space indent, double quotes, ES5 trailing commas, semicolons always.
  • Tailwind classes are auto-sorted inside cn, clsx, and cva.
  • Several accessibility rules are disabled project-wide, so lint passing doesn’t mean a component is accessible. Check keyboard and screen-reader behaviour yourself.
Install the Biome extension for your editor and set it as the default formatter for JavaScript, TypeScript, and JSON. Biome respects .gitignore, and skips src/mocks/fixtures/projects.mock.json, a large fixture that would be slow to format.

Troubleshooting

The mock API doesn’t have a handler for that route. Check the terminal for [mock-api] UNHANDLED <method> <path> and see the Mock API guide.
It’s usually formatting or import order, not a rule violation. Run pnpm lint:write.
The husky pre-commit hook runs Biome with --write on staged files and restages the result. That’s expected.
A stale node_modules after a dependency change is the usual cause.