← ClaudeAtlas

frontend-architecturelisted

Apply the Domain → Hook → Route layered architecture when creating or refactoring frontend features. Use this skill when adding a new page/feature or when a route file mixes business logic with UI rendering.
LDVerdier/rune · ★ 0 · Web & Frontend · score 58
Install: claude install-skill LDVerdier/rune
# Frontend architecture: Domain → Hook → Route pattern ## Pattern: Domain → Hook → Route All feature code must follow a three-layer separation: | Layer | Location | React dependency | Responsibility | |-------|----------|-----------------|----------------| | **Domain** | `app/domain/<feature>.ts` | None | Constants, types, pure functions (game rules, validation, computation) | | **Hook** | `app/hooks/use-<feature>.ts` | `useState` only | Thin adapter wiring React state to domain functions | | **Route** | `app/routes/<page>.tsx` | Full | JSX rendering, imports hook and domain constants | ### Domain layer (`app/domain/`) - **Zero React imports** — pure TypeScript only - Export all constants, type aliases, and pure functions - Functions accept state as arguments and return new state (no mutation) - Use `null` return to signal invalid operations (e.g. `tryChangeRank` returns `Ranks | null`) - Must be fully testable with plain Vitest (no DOM, no React) ### Hook layer (`app/hooks/`) - Holds `useState` and wires it to domain functions - Keeps the adapter thin (~25-40 lines) — no business logic here - Delegates all computation and validation to domain functions - Returns a clean API object for the route to consume ### Route layer (`app/routes/`) - Pure rendering: JSX, event handlers, and presentation helpers - Small presentation helpers (e.g. `rankTextColor`) stay in the route file if used only there - Imports the hook for state + actions, domain module for constants/types -