Just want the app running? Run the app locally is the two-command version.
This page is the reference for everything else.
Requirements
Scripts
Development
Development
Quality
Quality
Build & deploy
Build & deploy
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
Imports: one alias only
Imports: one alias only
@/* maps to ./src/*. There are no other path aliases.organizeImports assist. pnpm lint fails on
unsorted imports, pnpm lint:write fixes them.Tailwind v4: there is no tailwind.config
Tailwind v4: there is no tailwind.config
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.shadcn/ui
shadcn/ui
Configured in Generated files land 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.src/shared/components/ui/.Biome rules that bite
Biome rules that bite
noEnum: TypeScriptenumis banned. Use a union type or aconstobject.- 80-column lines, 2-space indent, double quotes, ES5 trailing commas, semicolons always.
- Tailwind classes are auto-sorted inside
cn,clsx, andcva. - Several accessibility rules are disabled project-wide, so lint passing doesn’t mean a component is accessible. Check keyboard and screen-reader behaviour yourself.
Editor setup
Editor setup
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
A request returns 501 in dev
A request returns 501 in dev
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.`pnpm lint` fails but the code looks fine
`pnpm lint` fails but the code looks fine
It’s usually formatting or import order, not a rule violation. Run
pnpm lint:write.My commit contains changes I didn't make
My commit contains changes I didn't make
The husky pre-commit hook runs Biome with
--write on staged files and restages the
result. That’s expected.Type errors after pulling
Type errors after pulling
node_modules after a dependency change is the usual cause.