Next.js
Shipping Faster: App Router Project Structure That Stays Clean
Folder layout, colocation, and conventions so your Next.js App Router project stays navigable as it grows.
A clear project structure makes it easy to find where to add or change code. For the App Router, a few conventions go a long way.
app/ is for routes and segment UI
Under app/, folders are routes; special files (layout, page, loading, error, not-found) define behavior. Keep route segments flat when possible: one folder per segment, one page.tsx per route. Nested layouts are fine, but avoid deep nesting of pages (e.g. more than three levels) unless you have a clear URL structure that needs it. Put route-specific UI (e.g. a dashboard sidebar) in the same segment folder or a nearby _components folder so it’s obvious what belongs to that route.
Where to put shared code
Put shared UI in components/ at the root (or src/components/ if you use src/). Split by domain or type: e.g. components/ui/ for design system primitives, components/forms/ for form pieces, components/blog/ for blog-specific blocks. Put hooks, utils, and lib code in lib/ or utils/; put types in types/ or next to the code that uses them. Colocate when it helps: e.g. a feature folder with its components and hooks inside, and only promote to components/ or lib/ when reused elsewhere.
Conventions that scale
Use a consistent naming: page.tsx, layout.tsx, loading.tsx, error.tsx, and optional not-found.tsx. For components, prefer one component per file and match the file name (e.g. Button.tsx exports Button). Use index files sparingly (e.g. components/ui/index.ts re-exporting) so imports stay explicit and refactors are safe. Keep Server Actions in the same file as the route or in an actions file next to the route; avoid a single giant actions/ folder for the whole app unless you like it.
app/
(marketing)/
page.tsx
layout.tsx
dashboard/
layout.tsx
page.tsx
_components/
Sidebar.tsx
blog/
[slug]/
page.tsx
components/
ui/
forms/
lib/
auth.ts
db.tsRoute groups like (marketing) keep layout and routes without adding URL segments. Use them to separate areas (marketing vs app) while sharing a root layout.
Summary
Keep app/ focused on routes and segment UI; put shared UI in components/ and shared logic in lib/. Colocate route-specific code; promote to shared when reused. Use consistent names and shallow enough structure so the app stays easy to navigate and ship from.