Skip to content

React / Next.js Standard

v1.0 — 2026-06-06 — applies to Transfera (TREX.UI) and future React apps.

Stack

React 19 + Next.js 15 App Router, TypeScript 5 strict, TailwindCSS, Radix UI, Zod, Zustand, Apollo Client, MSAL React.

Components & data

  • Server Components by default; add 'use client' only at interactivity leaves. Props crossing the boundary must be serializable.
  • Next.js 15 is uncached by default (fetch, GET route handlers, client router cache). Be explicit: revalidate, export const dynamic, cache: 'force-cache' — never rely on implicit caching.
  • Mutations via Server Actions with useActionState / useOptimistic. React 19: ref as prop (no forwardRef), use() API.
  • Layout: colocate by route segment under app/; route groups (group); private folders _folder.

TypeScript & validation

  • strict: true plus noUncheckedIndexedAccess. No any.
  • Validate all external data with Zod (API responses, env vars, form input) and infer types via z.infer — schemas are the source of truth.
  • Forms: React Hook Form + zodResolver.

State

  • Zustand: small single-purpose stores; select atomic slices (useStore(s => s.x)); never store derived state (compute in selectors).
  • Server data belongs in Apollo/Server Components, not Zustand.

Performance (items 28–30, accepted 2026-06-06)

  • Bundle budgets enforced in CI: size-limit (or equivalent) on route bundles, failing the PR build on regression; Lighthouse CI with a budget file on public pages (LCP, JS bytes, transfer size) where no auth is needed in the pipeline.
  • Core Web Vitals targets at p75: LCP < 2.5 s, INP < 200 ms, CLS < 0.1.
  • JS discipline: Server Components already minimize client JS — keep it that way; next/dynamic for heavy client widgets (maps, charts); import-on-interaction for third-party embeds.
  • Images: next/image exclusively (AVIF/WebP, explicit dimensions, lazy below the fold, priority on the LCP image).

Tooling

  • 2-space indent, LF, single quotes, Prettier default printWidth 80 (ratified — frontend does NOT follow the C# 180 rule); Prettier + ESLint (next/core-web-vitals) enforced in CI.

Sources: Server/Client Components · Next.js 15 · React 19 · Zod · Zustand