For a new Next.js project in 2026, use the App Router. That's the short answer, and it's what the framework itself recommends. The longer answer — why it changed, what it costs you in learning curve, and whether an existing Pages Router app is worth migrating — is what most comparison articles skip. This is our honest take after shipping production apps on both.
What actually changed
The Pages Router maps files in a `pages/` directory to routes, and every component is a client-side React component. You fetch data in special exported functions — getStaticProps at build time, getServerSideProps per request — and Next.js passes the result to your page as props. It's a simple, predictable model that a lot of people (including us) shipped happily for years.
The App Router uses an `app/` directory and makes React Server Components the default. Components run on the server unless you explicitly opt into the client with a 'use client' directive. Data fetching moves inside the component itself — an async component simply awaits its data — and the special getX functions disappear entirely. Alongside that come nested layouts that persist across navigation, and file conventions for loading and error states.
| Pages Router | App Router | |
|---|---|---|
| Directory | pages/ | app/ |
| Default component type | Client component | Server component |
| Data fetching | getStaticProps / getServerSideProps | async/await inside the component |
| Layouts | Manual, re-rendered per navigation | Nested layouts that persist |
| Loading states | Built by hand | loading.tsx convention |
| Error handling | Custom _error page | error.tsx per route segment |
| JS sent to browser | All component code | Only client components |
| Status | Supported, not deprecated | Recommended default |
The real benefit: less JavaScript reaches the browser
The headline feature isn't the folder rename — it's that server components never ship their code to the browser. A component that formats dates, queries a database, or renders a large block of static content contributes nothing to your JavaScript bundle. On content-heavy pages that difference is substantial, and it shows up directly in Core Web Vitals.
Nested layouts are the second genuine win. A dashboard shell, a sidebar, or a persistent navigation bar can be defined once and stay mounted while the content inside it changes. In the Pages Router that required workarounds; in the App Router it's the default behaviour.
The honest costs
- The mental model is genuinely harder. 'Does this run on the server or the client?' is a question you now ask constantly, and getting it wrong produces confusing errors. Hooks, event handlers, and browser APIs all require a client component.
- Caching has been the most common source of surprise. Data that seems like it should be fresh gets cached, or the reverse. It's well documented and the defaults have improved, but expect to spend real time understanding it.
- Third-party libraries occasionally need a client boundary wrapper. This was painful in 2023 and is mostly resolved in 2026 — most maintained libraries now ship correct directives — but you'll still meet the odd package that needs wrapping.
- There's more to learn before you're productive. A developer who knows the Pages Router well is not immediately productive in the App Router; budget a week or two of real project work, not an afternoon of reading.
Which should you choose for a new project?
The App Router, in almost every case. It's where the framework's development is focused, it's what new documentation and community answers assume, and starting on the Pages Router today means starting on the path you'll eventually migrate off. The learning curve is a one-time cost; being on the deprecated-in-spirit path is an ongoing one.
The exception worth naming: if you have a hard deadline, a team that knows the Pages Router deeply, and no time to absorb a new model, shipping on what your team knows is a legitimate engineering decision. That's a scheduling call, not a technical one — and if you're weighing framework choices more broadly, our guide to Next.js vs plain React covers the layer above this decision.
Should you migrate an existing app?
Not on principle alone. A Pages Router app that works, performs well, and isn't under active feature development is fine where it is — the Pages Router is supported, not deprecated, and 'migrate because it's newer' is how teams spend a quarter delivering nothing a user can see.
Migration earns its cost when you have a concrete problem it solves: bundle size hurting your Core Web Vitals, layout state you keep fighting, or a roadmap of new features you'd rather build on the current model. The practical approach is route by route — new features land in `app/`, existing routes move when you're already touching them — which spreads the work across normal development instead of stopping it.
What we use at Webaholic Studio
Every new project we start uses the App Router, and this site runs on it — Next.js 16, App Router, static export, which is why every page here is pre-rendered HTML that scores 100/100 on PageSpeed. We chose static generation deliberately; the reasoning is in our post on static sites vs server rendering.
For client projects on existing Pages Router codebases, we migrate incrementally and only when there's a reason to. If you're weighing this decision for a product in progress, it's the kind of thing we work through in a scoping conversation — see what we do or get in touch.
Frequently asked questions
Is the Pages Router deprecated?
No. The Pages Router remains supported in current Next.js versions and existing apps continue to work. What has changed is emphasis: new features, documentation, and community examples target the App Router first. Treat it as stable and maintained rather than actively evolving.
Can I use both routers in the same project?
Yes — `pages/` and `app/` can coexist, with the App Router taking precedence when both define the same route. This is the officially supported migration path and the reason moving over doesn't have to be a rewrite. Migrate one route at a time and ship continuously.
Does the App Router improve SEO?
Indirectly. Both routers serve server-rendered HTML that crawlers read fine, so neither has an inherent ranking advantage. The App Router helps by shipping less JavaScript, which improves loading metrics that do factor into ranking — and its metadata API makes per-page titles, descriptions, and structured data easier to get right.
How long does migrating a mid-sized app take?
There's no honest universal number — it depends on how much of your code assumes client-side execution and how many data-fetching functions need rethinking. What's reliable is the shape of the work: incremental route-by-route migration alongside normal feature development, rather than a dedicated freeze. Teams that try to migrate everything at once are the ones that stall.
Last updated: 24 August 2026