The Principle
Place files next to the code that uses them. Route-specific components go in the route folder. Shared components go in the nearest common parent. Globally shared code lives inpackages/.
Private Folders
Prefix folders with an underscore (_components/, _hooks/, _lib/) to opt them out of the routing system. Next.js treats these as private folders and ignores them for route matching.
This prevents component files from accidentally becoming route segments and keeps routing logic separate from UI code.
Where Things Live
| Scope | Location | Example |
|---|---|---|
| Single route | app/dashboard/_components/ | A chart that only the dashboard renders |
| Route group | app/(auth)/_components/ | Social login buttons shared by login and register |
| Single app | apps/app/src/components/ | A sidebar used across all routes in the app |
| All apps | packages/design-system/ | Buttons, cards, inputs from @repo/design-system |
Route Groups
Route groups wrap related routes without affecting the URL. Parenthesized folder names like(auth) and (marketing) organize code while keeping paths clean:
layout.tsx for shared UI like sidebars or navigation within that group.
Server and Client Boundaries
Keep"use client" at the leaf level. Page files and layouts run as Server Components by default. Push client interactivity (state, events, hooks) into the _components/ folder:
apps/app/src/app/dashboard/page.tsx
apps/app/src/app/dashboard/_components/stats-card.tsx
Colocating Non-Component Files
Routes can colocate more than components. Schema validation, types, and constants that belong to a single route live in the same folder:src/lib/ or src/hooks/ in the app, or to a shared package.
In a Monorepo
mf² splits shared code into packages. The colocation hierarchy extends across the monorepo:- Route folder: used by one page
- Route group
_components/: shared within a group - App-level
src/components/: shared across routes in one app @repo/design-system: shared across all apps- Other
@repo/*packages: shared utilities, hooks, configs
@repo/design-system serves every app. A component in dashboard/_components/ serves one page.
The hierarchy tells an agent where to put new code. Route-specific component: _components/ in the route folder. Shared across apps: @repo/design-system. Convention replaces guesswork.