Conventions
Code style, TypeScript, React, and import conventions for the monorepo.
Formatting
Biome only — no ESLint, no Prettier. The formatter is configured at the repo root
in biome.json.
- 4-space indent, single quotes, semicolons, trailing commas,
lineWidth: 120. pnpm format:checkruns format checks;pnpm formatapplies fixes including unsafe fixes such as Tailwind class sorting.
TypeScript
strict,noUncheckedIndexedAccess,noUnusedLocals,noUnusedParameters,composite.useImportTypeis enforced as a Biome error — all type-only imports must useimport type. Mixing value and type imports in one declaration (import { Foo, type Bar }) is also accepted.noUncheckedIndexedAccess: truemeans array/record index access returnsT | undefined. Do not paper over with!— handle theundefinedcase explicitly.
No unused variables, parameters, imports, or destructured props. Delete them — never
suppress with a leading underscore (_unused), void casts, or // biome-ignore.
The only exception is a rest pattern where the named keys are genuinely discarded:
const { skip, ...rest } = props.
React
- Server Components by default. Add
'use client'only when you need hooks, event handlers, or browser APIs. Never import aserver-onlymodule — or any file that transitively does — from a client component. - Trailing slashes on internal links (
trailingSlash: trueinnext.config.mjs). Allhrefvalues in app code must end with/. - Provider tokens guarded with
experimental_taintUniqueValue. Preserve that. - Async APIs in Next.js 16.
params,searchParams,cookies(),headers(), anddraftMode()are Promises.awaitthem in async functions; useReact.use()in sync components.
Errors
Never throw new Error(...). Use @nordcom/commerce-errors:
import { NotFoundError } from '@nordcom/commerce-errors';
throw new NotFoundError();If no existing class fits, add one — see Errors for the procedure.
Console
noConsole allows warn / error / info / debug only. Plain console.log fails lint.
Imports
@nordcom/commerce-*packages are workspace packages —workspace:*version for inter-workspace deps, never a version range.import typefor type-only imports — enforced by Biome.- Barrel files (
index.ts) are allowed in packages but avoided in apps — prefer direct imports so tree-shaking and code-splitting work correctly.
Comments
Comments must earn their place. Document the why — hidden constraints, workarounds, surprising behavior. If the code already says it, no comment needed. No section headers, no task notes, no restatements of what the code does.
JSDoc is required on every exported function and component. The block must include
purpose plus @param, @returns, and @throws where applicable. Same no-fluff rule
applies inside the block — describe intent and contract, not implementation.
Generated files
apps/docs/app/docs/(generated)/is generated by the docs build scripts — do not hand-edit files there.pnpm cms:genreruns the descriptor-driven CMS codegen — the admin editor-action wrappers,packages/cms/src/types/content-types.ts, and the Convex content-table validators (packages/convex/convex/tables/cms.ts) — after touching CMS field descriptors or editor manifests. The CI gate ispnpm cms:gen:check.