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:check runs format checks; pnpm format applies fixes including unsafe fixes such as Tailwind class sorting.

TypeScript

  • strict, noUncheckedIndexedAccess, noUnusedLocals, noUnusedParameters, composite.
  • useImportType is enforced as a Biome error — all type-only imports must use import type. Mixing value and type imports in one declaration (import { Foo, type Bar }) is also accepted.
  • noUncheckedIndexedAccess: true means array/record index access returns T | undefined. Do not paper over with ! — handle the undefined case explicitly.
Watch out

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 a server-only module — or any file that transitively does — from a client component.
  • Trailing slashes on internal links (trailingSlash: true in next.config.mjs). All href values in app code must end with /.
  • Provider tokens guarded with experimental_taintUniqueValue. Preserve that.
  • Async APIs in Next.js 16. params, searchParams, cookies(), headers(), and draftMode() are Promises. await them in async functions; use React.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 type for 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:gen reruns 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 is pnpm cms:gen:check.
Continue exploring

On this page