Webaholic Studio
Technical24 August 20269 min read

Next.js App Router vs Pages Router: A Developer's Honest Take

What actually changed between the Pages Router and the App Router, which one to pick for a new project, and whether an existing app is worth migrating.

B

Boris

Founder, Webaholic Studio

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 RouterApp Router
Directorypages/app/
Default component typeClient componentServer component
Data fetchinggetStaticProps / getServerSidePropsasync/await inside the component
LayoutsManual, re-rendered per navigationNested layouts that persist
Loading statesBuilt by handloading.tsx convention
Error handlingCustom _error pageerror.tsx per route segment
JS sent to browserAll component codeOnly client components
StatusSupported, not deprecatedRecommended 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

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.

Worth knowing: both routers can run in the same application. Next.js supports `pages/` and `app/` side by side, which is what makes incremental migration realistic rather than a big-bang rewrite.

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.

Next.jsApp RouterReactarchitecturefrontend

Last updated: 24 August 2026

Work with us

Ready to build something?

Tell us about your project. We'll get back to you within 24 hours with a clear next step.

Related articles