How I Structure Large Next.js Projects — Folder Architecture Guide
Bad nextjs folder structure does not show up on day one. It shows up at month six when three developers search for the checkout form hook and find four copies. I reorganised a client dashboard after exactly that — this guide is the tree I use now on large App Router projects, why each folder exists, mistakes from my first Next.js apps, and the 10-second findability rule . Real folder tree — production-shaped layout my-app/ ├── app/ # routes only — thin pages │ ├── (marketing)/ # route group — shared layout, no URL segment │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── pricing/page.tsx │ ├── (dashboard)/ │ │ ├── layout.tsx │ │ └── orders/page.tsx │ ├── api/ # route handlers │ │ └── webhooks/stripe/route.ts │ ├── layout.tsx # root layout │ └── globals.css ├── components/ # shared UI — buttons, cards, shell │ ├── ui/ │ └── layout/ ├── features/ # business domains — colocated logic │ ├── auth/ │ │ ├── components/ │ │ ├── hooks/ │ │ └── actions.ts │ └── orders/ │ ├── components/ │ ├── api.ts │ └── types.ts ├── lib/ # server + shared utilities │ ├── db.ts │ └── env.ts ├── hooks/ # truly global client hooks ├── types/ # global TS types ├── data/ # static data, blog posts list └── public/ Routes live in app/ . Business logic lives in features/ . Generic design system pieces live in components/ui . That separation is the whole game. Why each folder exists Folder Purpose Do not put here app/ URLs, layouts, loading.tsx Fat business logic features/ Domain modules (orders, auth) Generic Button components/ui Reusable primitives Order-specific tables lib/ DB clients, env validation React components app/api Webhooks, REST edge cases Every form POST (prefer actions) Thin pages — route files under 40 lines // app/(dashboard)/orders/page.tsx — orchestration only import { OrderTable } from "@/features/orders/components/OrderTable"; import { getOrders } from "@/features/orders/api"; export default async function OrdersPage() { const orders = await getOrders(); return ( <section> <h1>Orders