Next.js 10,514 ships two routers. The Pages Router (pages/) is the original design from 2016: one file, one route, one default-exported component, with data supplied by getStaticProps or getServerSideProps before the component runs. The App Router (app/) arrived in beta with Next.js 13 in October 2022 and became the recommendation in 13.4.
The difference is not a folder name. In pages/, every component is a Client Component: the server renders it once to HTML, ships the whole tree as JavaScript, and hydrates. In app/, every component is a Server Component until you write 'use client'. Everything else follows.
| Concern | pages/ | app/ |
|---|---|---|
| Route file | pages/books/[id].js | app/books/[id]/page.js |
| Shared shell | _app.js, _document.js | nested layout.js files |
| Data for a page | getServerSideProps | await inside the component |
| Static data | getStaticProps, getStaticPaths | "use cache", generateStaticParams |
| HTTP endpoints | pages/api/*.js | app/**/route.js |
| 404 and errors | 404.js, _error.js | not-found.js, error.js |
| <head> tags | next/head | metadata exports |
| Router hooks | next/router | next/navigation |
The two directories coexist, which is the intended migration path: move one route at a time, starting with a leaf page that has no shared layout, and delete pages/ when it is empty. Where they overlap, app/ wins. The cost is that navigation between the routers is a hard navigation — a full document load, no client-side transition — and next/link does not prefetch across the boundary, so group related routes to keep users on one side. A component used by both can import next/compat/router, which returns the Pages Router object under pages/ and null under app/.
For a new project, choose the App Router: every feature added since 2023 lives there, and the Pages Router now receives fixes rather than features. Keep pages/ only when a library has not been updated for Server Components.