Frontend UI architecture and code organization for React & Next.js — deciding WHERE code should live (folder/file structure, feature- vs type-based layout, colocation, where components / hooks / business logic / utils / constants / types / Server Actions belong, module boundaries and imports, and organizing the Server/Client boundary). Use this skill WHENEVER the user asks how to structure or organize a React/Next.js project, where a file/component/hook/type should go, how to split a large component, where to put business logic or data access, utils-vs-lib-vs-helpers, or barrel files — or asks for an architecture/structure review — even if they don't say the word 'architecture' and even though such questions can look answerable directly. Structure & organization only — not in-component coding rules (use react-best-practices) or Next.js API/feature mechanics (use next-best-practices).
How this skill is triggered — by the user, by Claude, or both
Slash command
/engineering-paved-path:frontend-ui-architectureWhen to use
Trigger phrases: 'where should this file/component/hook go', 'how should I structure the folders', 'feature-based vs type-based', 'where do I put business logic / constants / types', 'utils vs helpers vs lib vs services', 'should I use barrel files', 'where does the API/data layer live', 'organize this React/Next project', 'review the project architecture', 'where to put use client / Server Actions'.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Decisions about **where code lives and how the project is organized** for React & Next.js apps:
Decisions about where code lives and how the project is organized for React & Next.js apps: folder structure, file placement, module boundaries, and the Server/Client boundary as an organizational concern.
This skill is about structure, not coding style. For in-component correctness and anti-patterns (hooks, state, rendering, memoization) use react-best-practices; for Next.js API/feature usage (RSC mechanics, data APIs, metadata, optimization) use next-best-practices.
When the honest answer is "it depends," default to these — they're the calls worth committing to explicitly, the ones that keep a codebase from drifting. The detail behind each is below.
src/{app, components/ui, features/<domain>, lib, hooks, utils, types, config}. Type-only folders are fine for a throwaway; commit to features past
~15–20 components instead of relitigating it later.index.ts; features never import each other's internals.
Enforce it (ESLint import/no-restricted-paths), don't just intend it — this is the boundary that
prevents the mess.lib/ = stateful integrations (db, auth, SDK clients); utils/ = pure functions. Never a
junk-drawer utils.ts — name files by what they provide (date.ts, currency.ts).server-only data-access layer is the sole reader of process.env/DB; Server Actions
stay thin and delegate to it. Secrets never enter a "use client" module graph."use client" only on interactive leaves;
pass Server Components as children into Client Components (a Client Component can't import one);
wrap context in a small client Providers so the rest of the tree stays server-rendered.Load on demand — keep this file in context, open a reference only when the task needs that depth.
Apply these in order — they resolve most "where does this go?" questions.
src/ with a few
folders. Introduce features/ and deeper boundaries only when the app grows. Don't pre-build
structure for scale you don't have.auth,
billing), not what it is (all-components, all-hooks). Type-based grouping is fine for small apps.components, hooks, lib, utils, types) →
features → app/routing. No cross-feature imports. If two features share code, lift it to shared.src/: app/ (or routing), components/ (shared UI), features/, hooks/, lib/,
utils/, types/, config/, stores/. These names are conventions, not framework rules — be consistent.features/<name>/{components,hooks,api,utils,types}
plus an optional index.ts public API. Internals stay private to the feature.components/, hooks/, utils/ only) is acceptable for small apps; migrate to
feature-based as the count of files-per-folder grows past comfort.| Code | Default location | Promote / escalate when |
|---|---|---|
| Component used by one feature | features/<f>/components/ | a 2nd feature needs it → components/ |
| Shared UI primitive (Button, Card) | components/ui/ | — |
| Custom hook (feature-specific) | features/<f>/hooks/ | reused elsewhere → hooks/ |
| Business logic | a custom hook, or features/<f>/api/services; server-side → a DAL | — |
| Constant used once | top of the file that uses it | feature-wide → <f>/constants.ts; app-wide → config/ |
| Pure, generic helper | utils/ | — |
| Project-specific helper | beside its feature (<f>/utils or *.helpers.ts) | becomes generic → utils/ |
| Type used once | same file as its use | shared → <f>/types.ts or *.types.ts; cross-package → shared package |
| API / data-fetch functions | features/<f>/api/ or lib/api | — |
| Server Action (Next.js) | <f>/actions.ts / _actions/, thin → delegates to DAL | — |
| Third-party client/init (db, auth, SDK) | lib/ | — |
Definitions and the reasoning (utils vs helpers vs lib vs services, type placement, business-logic placement) are in references/where-things-go.md.
import/no-restricted-paths): shared may
not import from features; features may not import from each other; routing/app sits on top.@/*) instead of ../../../ relative chains.index.ts): a thin, per-feature public-API barrel is fine. Avoid large or
app-wide barrels and deep barrel chains — they hurt tree-shaking and dev-server/HMR and create
import cycles. Prefer direct imports for internal and shared modules.When and whether to split — not how to write the component (that's react-best-practices).
children/slots; "lift content up" (give a wrapper its content via
children when it doesn't use it for logic); "push state down" to the component that needs it.children fails to remove the
prop drilling.Where state lives (organizational). For state-hook coding rules, see react-best-practices.
useState/useEffect. Keep it out of UI-state stores.Key rules (full detail in references/nextjs-app-router.md):
app/ is for routing only — push logic into features/.app/ (only page/route output ships); opt subtrees out of
routing with private folders (_folder); organize routes without changing URLs via route
groups ((group))."use client" to the leaves of the tree; pass Server Components into Client Components as
children/props rather than importing them.server-only package, a data-access layer); process.env and
secrets stay server-side.<feature>/actions.ts) and delegate to a server-only data layer.lib vs utils convention: lib/ = stateful integrations (db, auth, SDK clients), utils/ =
pure helpers. (Officially both names are arbitrary — pick one convention and hold it.)constants.ts, types.ts, hooks.ts. Suffix shared kinds:
*.types.ts, *.helpers.ts, *.store.ts.is/has/should. Event handlers: handle* (defining) / on* (prop). Utilities:
get/set/use. HOCs: with*.utils.ts / helpers.ts / misc.ts collecting unrelated functions — name files
by what they provide; group by cohesion.children/composition extraction would remove.shared/ abstraction with a single consumer.npx claudepluginhub rostk/my-monkeys --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.