Skip to main content

ADR-008 — React style guidelines + thin-app architecture

reference · frontend · updated 2026-06-23 · source

  • Status: Accepted
  • Date: 2026-06-23
  • Owner: Frontend
  • Related issue: #715 (depends on #716, Next 16 upgrade)

Context

  • React/Next code style + architecture was governed by scattered guardrails (frontend-guardrails.md, admin-ui-conventions.md, grid-system.md) with no single contract for component architecture, data patterns, composition, or where reusable UI lives.
  • We now run Next 16 / React 19 / Turborepo (#716) across three Next apps (admin, console, comprender) that share @tedos/admin-ui (+ the neutral @tedos/ui foundation).
  • José wants a performant, solid, antipattern-free codebase where the apps are thin and the reusable React lives in the UI packages — plus a swarm refactor to enforce it.
  • Needs an ADR now because it ratifies an architecture decision (thin apps), not just style.

Decision

Adopt a single citable React style + architecture contract — .claude/rules/react-style-guidelines.md — grounded in Vercel's official guidance, with aggressive thin-app architecture.

  • Thin apps (A1–A5): apps own only routing, RSC data-fetching seams, auth (proxy.ts), env, and thin page shells. All presentational/reusable UI lives in @tedos/admin-ui (admin skin) or @tedos/ui (neutral foundation). apps/*/src/components/** trends to empty.
  • Server-first (RSC default, client only at interactive leaves), waterfall elimination (Promise.all, Suspense, React.cache), bundle discipline (subpath imports, next/dynamic), composition over boolean props (compound components, explicit variants, children), React 19 idioms (no forwardRef, use()), and re-render hygiene.
  • A 12-item antipattern table (AP1–AP12) is the swarm's fix-list.
  • Sources cited per sectionvercel-react-best-practices, vercel-composition-patterns, next-best-practices, turborepo — the rule is the local digest; the skills are the canonical explanation.
  • Scope boundary: this governs React code style + architecture. Visual tokens/brand stay with the Designer + admin-ui-conventions.md / color-scope.md / grid-system.md. It does not change tokens, brand, or the design system.

Consequences

Positive

  • One bible for every React contribution (human or agent); reviews cite a rule ID.
  • Maximal reuse: a component is written once, in a package, consumed by all apps.
  • Performance + a11y are contractual, not aspirational; antipatterns are a review blocker.

Negative / trade-offs

  • Aggressive extraction is a large, prod-facing refactor (separate effort) — real blast radius; mitigated by a read-only audit pass before the fix swarm, and per-app verification.
  • The @tedos/admin-ui barrel vs. tree-shaking tension forces subpath-export discipline (D1).
  • Some app-specific components legitimately stay in the app; "thin" is a strong default, not absolute.

Follow-ups required

  • .claude/rules/react-style-guidelines.md (new) + this ADR + knowledge/INDEX.md row.
  • A separate refactor effort (audit → one PR) to bring admin/console/comprender into line.
  • Pair with playwright-best-practices (testable) + web-design-guidelines/axe (accessible) — not covered by the perf/composition skills.

Alternatives considered

OptionWhy not
Keep guardrails scatteredNo single contract; the swarm has no bible to enforce against.
Rules only, no thin-app architectureMisses José's core ask — apps purely compose package components.
Per-app component librariesViolates monorepo "one workspace per concern"; defeats reuse across the app fleet.

References

  • .claude/rules/react-style-guidelines.md (the enforced rule)
  • Skills: vercel-react-best-practices, vercel-composition-patterns, next-best-practices, turborepo
  • Next 16 upgrade: https://nextjs.org/docs/app/guides/upgrading/version-16 (#716)
  • Sibling rules: admin-ui-conventions.md, frontend-guardrails.md, monorepo-turbo.md, color-scope.md