Use feature-based architecture for React, Next.js, and TypeScript. Organize by domain, not file type.
When to Use
- Starting React or Next.js project
- Deciding where new code belongs
- Reorganizing large codebase
- Preventing cross-feature imports
Goal
Keep features independent. Keep shared code truly shared. Compose features at app layer.
Rules
- Code flows one way: shared → features → app.
- Features cannot import other features.
- App can compose multiple features.
- Shared code cannot import app or features.
- Add only folders needed now.
- Move one-feature code into that feature.
Base Structure
src/
app/ routing, layouts, providers
components/ shared UI
features/ domain modules
hooks/ shared hooks
lib/ library clients and wrappers
types/ shared types
utils/ shared utilities
Feature:
src/features/users/
api/
components/
hooks/
types/
utils/
Create only folders used by that feature.
Placement
- Route/page:
src/app/ - Shared UI:
src/components/ - Feature UI:
src/features/[feature]/components/ - Feature API:
src/features/[feature]/api/ - Feature type:
src/features/[feature]/types/ - Feature utility:
src/features/[feature]/utils/ - Shared utility:
src/utils/
Flow
- Identify domain or feature.
- Check if code is used by one feature or many.
- Put one-feature code inside feature.
- Put reused code in shared folders.
- Compose cross-feature screens in app layer.
- Add lint rules for import boundaries.
Output
## Project Structure Decision
Code: [thing being placed]
Scope: [feature-specific / shared / app]
Location: [path]
Reason: [why]
Import boundary:
- Can import from: [allowed]
- Must not import from: [blocked]