ADR-0001: Feature vertical slices + folder-per-component

  • Status: Accepted
  • Date: 2026-05-30
  • Scope: core (any React frontend)

Context

A React app sprawls when components, styles, hooks, and API calls are organized
by type (all hooks here, all styles there). We want each feature to be a
self-contained unit that’s easy to find, move, and reason about.

Decision

Feature-based vertical slices. Each page owns its full slice:

pages/[Page]/
├── index.tsx              # calls use[Page]Page(), renders
├── styles.ts             # all styled.X for the page
├── hooks/                # use[Page]Page (logic) + thin use[Resource] query/mutation hooks
├── schemas/              # Zod schemas, createSchema(t) for i18n-aware messages
└── components/[Name]/     # page-specific subcomponents (same folder pattern)

Folder-per-component. Every component/atom/subcomponent is a folder
<Name>/{index.tsx, styles.ts}:

  • index.tsx contains zero styled.X declarations — all styling is in
    styles.ts (tagged templates, so .ts not .tsx).
  • Generic atoms live in src/components/; page-specific ones under the page’s
    components/. Pages don’t reach into other pages’ internals.

Supporting conventions:

The authoritative, current operational detail is in each app repo’s
CLAUDE.md; this ADR records the structural decision and its rationale.

Consequences

  • A feature is one folder you can read top-to-bottom; deleting/moving it is clean.
  • index.tsx/styles.ts separation keeps JSX readable and styling greppable.
  • More folders/files per feature, accepted for locality and consistency.