Folder Structure
A feature-based folder structure so you always know where a file goes — and why it belongs there.
Principle
A good folder structure answers one question instantly: 'where does this file go?' Feature-based organization groups everything related to a feature together — its components, hooks, and data — so you spend time building, not searching. When a feature grows or gets deleted, everything moves together.
If you can't decide where a file goes in under 10 seconds, your structure is too abstract. Feature-based organization should make the answer obvious.
Rules
- check_circleFeature-based groupingEverything related to a feature lives in src/features/[name]/ — its components, hooks, and data together.
- check_circleCo-locationTests, types, and constants live next to the code they describe. Avoid global /types or /constants folders.
- check_circleNo cross-feature importsFeatures never import directly from each other. Code needed by multiple features moves to src/shared/.
- check_circlePublic API via index.tsEach feature exposes only what needs to be exposed via an index.ts file. Internals stay internal.
Pattern
src/ ├── app/ # Next.js routing only — no business logic here ├── features/ # One folder per domain feature │ ├── cookbook/ │ │ ├── components/ │ │ ├── hooks/ │ │ ├── data/ │ │ └── index.ts # Public API — only export what others need │ └── examples/ │ ├── components/ │ ├── hooks/ │ └── index.ts ├── shared/ # Truly cross-cutting code │ ├── components/ # Used by 2+ features │ ├── hooks/ │ ├── stores/ │ └── utils/ ├── lib/ # External service clients (API, query client) └── ui/ # Design system primitives (Button, Input, etc.)
Implementation
Version Compatibility
Requires React 19+ and the latest stable versions of all dependencies shown.
Next.js adds the app/ directory for file-based routing. Route logic (pages) lives in app/, all business logic stays in features/.
src/ ├── app/ │ ├── layout.tsx # Root layout │ ├── page.tsx # Landing page → renders <LandingPage /> │ ├── (examples)/ # Route group — no URL segment │ │ └── forms/page.tsx # Renders <UserForm /> from features/ │ └── nextjs/ │ └── cookbook/ │ └── [slug]/page.tsx ├── features/ │ └── landing/ │ └── components/ │ └── LandingPage.tsx # Actual component lives here └── shared/