Frontend/UI architecture and code organization for a Next.js App Router + React codebase. Use when deciding WHERE code should live — folder structure, where to put a component/constant/util/hook, how to split a component, where business logic belongs, colocation vs shared. Trigger phrases: "where should this go", "folder structure", "how to split this component", "feature folder", "utils vs helpers", "business logic location", "colocation".
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering-paved-path:frontend-architectureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
How to organize a Next.js App Router + React frontend: **where code lives, how to split it,
How to organize a Next.js App Router + React frontend: where code lives, how to split it, and which direction dependencies flow. This skill is about placement and structure only.
For React runtime patterns (hooks, derived state, memoization, a11y), see
react-best-practices; for Next.js runtime patterns (RSC boundaries, data fetching,
metadata), see next-best-practices — both in this same plugin.
Detailed annotated folder map: structure.md. Sources & rationale: README.md.
Put code as close as possible to where it is used. Move it up only when a second consumer appears.
Used by ONE route/feature? → colocate inside that route segment (app/<route>/_components, _lib)
Used by TWO+ routes? → promote to a shared top-level folder (components/, lib/)
Used everywhere / app-wide? → top-level shared (lib/, components/, i18n/)
Premature shared abstractions are the most common mistake. Duplicate once before extracting (AHA — Avoid Hasty Abstractions). A "reusable" helper with one caller is just indirection.
Code flows one way. Lower layers never import from higher ones:
lib → components → app (routes/features)
lib/ (utils, hooks, clients) imports nothing from components/ or app/.components/ import from lib/, never from a specific route under app/.app/ composes components/ + lib/; it does NOT import from a sibling route.<frontend>/src/
├── app/ # Next.js App Router — routing + per-route (feature) code
│ └── <route>/
│ ├── page.tsx # makes the route public; thin — composes components + hooks
│ ├── layout.tsx # shared shell for the segment
│ ├── _components/ # route-private components (not routable)
│ │ └── <Name>/ # PascalCase folder: Name.tsx (+ hooks/helpers/types colocated)
│ └── _lib/ # route-private helpers/queries/actions (optional)
├── components/ # SHARED components reused across routes (grouped by area)
├── lib/ # SHARED utils, clients, config
│ └── hooks/ # SHARED hooks reused across routes
├── i18n/ # i18n setup + messages, if your app is localized
└── shared-contracts/ # types/contracts shared with your backend — edit at source
app/<route>/ prefixed with _ is private: safely colocated, never routable.page.tsx (or route.ts). Colocating other files is safe.(group) route groups only to share a layout / organize routes without changing the URL.components/ only on reuse.children / composition instead of drilling props.| Kind | Where | Rule |
|---|---|---|
| Route-private component | app/<route>/_components/<Name>/ | default home for new UI |
| Shared component | components/<area>/ | only after 2nd consumer |
| Constants | colocated next to use; promote to lib/ or a feature *.constants.ts when shared | enum-like, copy, config values |
| Pure utils | lib/ (shared) or _lib/ (route) | no side effects, no I/O — input → output only |
| Business logic | custom hook (lib/hooks/ or route _lib) or lib/ service | NEVER in the component body |
| Data access / I/O | lib/ client/service or Next.js Server Action in _lib | talking to the outside world |
| Shared hook | lib/hooks/ | reused across routes; client-side |
| Types | colocated *.types.ts; shared types in lib//shared-contracts | reuse contracts shared with your backend |
lib/; this is where side effects belong — not in utils.If a "util" has side effects, it isn't a util — it's a service. Name it accordingly and move it.
page.tsx / layout.tsx thin: they wire routing and compose; logic lives in _components/_lib._private folders to separate UI/logic from routing and avoid future naming conflicts.lib/_lib (server side).components/→app/ or lib/→components/ imports.page.tsx/layout.tsx are thin; logic is in hooks/_lib, not component bodies.utils are pure; anything with I/O lives in a service/client under lib/.npx claudepluginhub kolodgeeva/dev-digest-ai-marketplace --plugin engineering-paved-pathGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.