I am a...
Learn more
How it worksPricingFAQ
Account
May 19, 2026 · 10 min read · Cadence Editorial

Cost to migrate from Pages Router to App Router (Next.js)

cost to migrate pages router app router — Cost to migrate from Pages Router to App Router (Next.js)
Photo by [Lukas Blazek](https://www.pexels.com/@goumbik) on [Pexels](https://www.pexels.com/photo/person-encoding-in-laptop-574071/)

Cost to migrate from Pages Router to App Router (Next.js)

Migrating a Next.js app from the Pages Router to the App Router in 2026 typically costs $8,000 to $250,000 in engineering time, depending on app size. A small app under 30 routes lands in the $8k to $20k range, a medium app (30 to 100 routes) runs $25k to $70k, and an enterprise app with 100+ routes and heavy third-party hydration sits between $80k and $250k.

The Pages Router still works fine in Next.js 15. Vercel has committed to maintaining it. So the question is not "can we wait" (you can) but "what does it actually cost when we move." Below is the cost model we use at Cadence after watching dozens of these migrations ship through our engineer pool.

Why the cost range is so wide

Three things drive almost the entire spread:

  • Route count. Each route is a small refactor: a getServerSideProps deletion, a server-component conversion, a <Layout> collapse into layout.tsx. Multiply by 200 routes and the hours add up.
  • Data-fetching density. Apps with heavy getServerSideProps or getStaticProps use cost more per route than apps that already fetched client-side with SWR or TanStack Query.
  • Third-party libraries that hydrate on the client. Stripe Elements, Intercom widgets, Sentry replay, certain charting libraries, and anything that touches window on import will all need wrapping in "use client" boundaries or dynamic imports. Each one is a 30 to 90 minute fire drill the first time you hit it.

If you want the step-by-step playbook for actually doing the migration, our companion piece Next.js Pages to App Router migration guide covers the code patterns. This article is purely about budget, scope, and when not to bother.

Cost by app size

Here is what we see across real migrations on the platform. Numbers assume a mid-tier engineer at $1,000/week, fully working on the migration with no other interruptions.

App sizeRoutesEngineer-weeksCost (mid tier)Calendar time
Small<30 routes, light data fetching8 to 20 weeks (split across 1 to 2 engineers)$8,000 to $20,0004 to 8 weeks
Medium30 to 100 routes, moderate third-party use25 to 70 weeks total$25,000 to $70,0008 to 16 weeks
Enterprise100+ routes, heavy auth, multi-tenant, complex middleware80 to 250 weeks total$80,000 to $250,0004 to 9 months

The calendar time is shorter than the engineer-weeks because most teams parallelize. A medium migration with 3 engineers in parallel ships in 8 to 12 weeks instead of 25.

What the budget actually buys you

For a small app (<30 routes, the typical Series A SaaS dashboard), the migration covers:

  • Rewriting _app.tsx and _document.tsx into app/layout.tsx and a root <Providers /> component (4 to 8 hours, including style and font handling)
  • Converting getServerSideProps to async server components or unstable_cache (1 to 3 hours per route)
  • Splitting interactive components into "use client" boundaries (30 to 90 minutes per file)
  • Replacing next/router with next/navigation and refactoring any router.events listeners (4 to 12 hours total)
  • Updating API routes from pages/api/* to app/api/*/route.ts handlers (1 to 2 hours per route)
  • Migrating middleware, auth callbacks, and _error.tsx patterns (8 to 20 hours)
  • Regression testing, fixing hydration warnings, deploying behind a feature flag (10 to 40 hours)

Medium and enterprise apps add multi-tenant routing, parallel routes, intercepting routes (think modals over a feed), streaming with Suspense, partial prerendering for marketing pages, and a longer tail of obscure third-party library breakage.

Cost breakdown by approach

We see five common paths to ship this migration. The right one depends on whether you already have a strong in-house team and how comfortable you are with App Router idioms.

ApproachCostTimelineProsCons
In-house team (US salaries)$30k to $200k+ in fully loaded cost3 to 9 monthsTeam owns the code long-term; deep contextPulls senior engineers off roadmap; opportunity cost is real
Dev agency (US/EU)$40k to $300k2 to 6 monthsProject management included; predictable deliveryAgency rates ($150 to $300/hr); often no Next.js specialists
Freelancer (Upwork, Toptal)$15k to $120k3 to 8 monthsCheaper than agencyQuality variance is huge; vetting takes weeks
Toptal$25k to $180k6 to 10 weeks to startPre-vetted; reliable$80 to $200/hr; long onboarding; minimum engagement length
Cadence$500 to $2,000/week per engineer48-hour trial, ship in 4 to 16 weeksAI-native engineers, weekly billing, replace any week, no notice periodLess suited to large enterprise procurement with NDA/MSA cycles

For a small-to-medium migration, booking a senior engineer at $1,500/week for 8 weeks puts the total at $12,000. That is roughly what one US senior engineer costs in two weeks of fully loaded salary plus benefits. The trade-off is you do not own the headcount long-term; you book for the migration, then release.

Hidden costs most quotes miss

Every quote you get will be wrong by some predictable line items. Budget an extra 15 to 30% on top of the headline number for these.

1. getServerSideProps is not a one-line swap

It looks easy in the docs. In practice, your getServerSideProps is probably doing three things: fetching data, reading cookies, and setting cache headers. The App Router splits those into three different APIs: async server components for fetching, the cookies() helper from next/headers, and revalidate exports or unstable_cache. Each route is a small design decision, not a copy-paste.

Budget impact: an extra 30 to 50% on every route that touches getServerSideProps.

2. _app.tsx and _document.tsx need a wholesale rewrite

The new app/layout.tsx is not a 1-for-1 replacement. Things that lived in _app.tsx (global state providers, theme providers, analytics scripts, error boundaries) need to be split between a server-rendered layout.tsx and a client <Providers> wrapper. Things that lived in _document.tsx (custom <html> tags, font preloading, CSP) move into layout.tsx and next/font.

If you used a custom _document.tsx for CSP nonces or weird SSR hacks, expect 1 to 3 days of plumbing.

3. Data-fetching pattern shift

Apps built on the Pages Router usually use SWR or TanStack Query for everything. App Router makes server fetching the default. The right answer is rarely "rewrite all your client hooks to server components"; it is usually "keep the hooks, but move the initial render server-side and pass the data down as initialData."

That hybrid pattern is the right answer 80% of the time, and it is also not in most migration guides. Engineers without App Router muscle memory will either over-rewrite (turning every component into a server component and breaking interactivity) or under-rewrite (leaving everything client-side and missing the SEO wins). Either mistake costs 2 to 4 weeks of rework.

4. Third-party library hydration mismatches

This is the worst surprise. Libraries that worked fine in Pages Router can throw hydration errors in App Router because they read window at import time. The usual suspects:

  • Stripe Elements (needs a "use client" wrapper)
  • Intercom and Drift widgets (load via next/script with strategy="lazyOnload")
  • Sentry session replay (config changes)
  • Recharts, Victory, certain D3 wrappers (dynamic import with ssr: false)
  • Older versions of react-select, react-datepicker, and react-dnd

Each of these is a 30 to 90 minute fire drill the first time you hit it. Multiply by the number of UI libraries in your package.json. We see 5 to 15 of these per medium migration.

5. Middleware and auth callback rewrites

If you use NextAuth (now Auth.js), Clerk, or Supabase Auth, your middleware probably needs adjusting. Edge runtime constraints are stricter in App Router. Callback URLs change. Cookie handling moves from req.cookies to the cookies() helper.

Budget 1 to 3 days for an auth-heavy app, more if you have multi-tenant subdomain routing.

When you should NOT migrate

The honest answer for many apps is: not yet, or not ever.

Skip the migration if:

  • Your app is shipping fine, has no SEO problems, and has no roadmap features blocked by App Router. Streaming, partial prerendering, and parallel routes are great, but if you do not need them, you are paying $25k+ to feel modern.
  • You are within 12 months of a full rewrite anyway. Migrating an app you plan to replace is just budget on fire.
  • Your app is mostly an SPA with one or two SSR pages. Move those two pages to a separate marketing site or keep them on Pages Router. The mixed approach is supported.
  • You depend on a Pages-Router-only library you cannot replace. Some niche CMS adapters and older auth providers still assume the Pages Router lifecycle.

We have advised at least four founders in the last quarter to defer migration entirely. The TanStack Query + Pages Router stack is still excellent in 2026 and Vercel has not deprecated it. If you are weighing this against the cost to build a full Next.js application from scratch for a green-field project, that is a different decision; for green-field, just start on the App Router.

How to reduce migration cost without cutting corners

Five things that have moved the needle on actual budgets we have seen:

  1. Migrate route by route behind a feature flag. Next.js supports the App Router and Pages Router side by side. Ship the new versions to 1% of traffic, then 10%, then 100%, route by route. This kills 80% of the regression-bug risk.
  2. Lock the data-fetching pattern before you start. Decide upfront whether you are going "server-first with initialData" or "client-first with selective server components." Write a 1-page ADR. Cuts the rework rate dramatically.
  3. Migrate the hottest routes last, not first. Counterintuitive, but it lets your team build muscle on low-stakes routes before touching the dashboard.
  4. Pair an AI-native engineer with Cursor or Claude Code on the route conversions. Pattern-matched refactors are exactly what these tools are good at. Every engineer on Cadence is AI-native; vetted on Cursor, Claude Code, and Copilot fluency before they unlock bookings, and we see 2 to 3x throughput on this kind of work.
  5. Cap the migration at a fixed scope and ship. Do not add "while we are in there" refactors. That is how a 6-week migration becomes a 6-month rewrite. If you want a structured framework for what to cut, our piece on the cost to build an admin dashboard covers the same scope-discipline trap.

If you want a senior engineer on this for 8 to 12 weeks, the math is straightforward: $1,500/week x 10 weeks = $15,000 total, with a 48-hour trial so you can verify fit before you commit. Book one through the Cadence founder onboarding and you will have a shortlist of vetted engineers in 2 minutes.

The fastest path from "we should migrate" to shipped

  1. Spend 2 hours auditing your app. Count routes, list every getServerSideProps, list every package.json dependency that touches window. This single document tells you whether you are in the small, medium, or enterprise bucket.
  2. Decide on the data-fetching pattern. Server-first, client-first, or hybrid. Write the 1-page ADR.
  3. Get an engineer started this week. If you have App Router muscle in-house, great. If not, the fastest path is to book a senior or lead engineer through Cadence: 48-hour trial, weekly billing, replace anyone who is not landing PRs by day 3. The platform's median time to first commit is around 27 hours.

If you are sizing this migration right now, book a senior engineer on a 48-hour trial through Cadence. You will know within 2 days whether they can ship the pattern, and you only pay $1,500/week after that. No notice period, no recruiter, no minimum engagement. Compared to the $25k retainer most agencies require to start, the risk profile is very different.

FAQ

How long does a Pages-to-App-Router migration take?

A small app (<30 routes) takes 4 to 8 calendar weeks with 1 to 2 engineers. A medium app (30 to 100 routes) takes 8 to 16 weeks with 2 to 3 engineers in parallel. Enterprise apps (100+ routes) typically run 4 to 9 months. Most of the variance comes from how much hydration-sensitive third-party code you have, not from raw route count.

Can I run Pages Router and App Router in the same Next.js app?

Yes, and you should. Next.js supports both routers side by side in the same project. The recommended migration path is to ship the App Router version of each route alongside the existing Pages Router version, then cut traffic over with a feature flag. This is the single biggest risk-reduction technique we have seen.

Is the migration worth it if my app is shipping fine?

Often, no. The App Router unlocks streaming, partial prerendering, server actions, and parallel routes. If none of those is blocking a feature on your roadmap, you are paying real money for marginal modernization. Defer until you have a concrete use case (SEO on a marketing page, a complex modal flow, faster TTFB on a dashboard).

What is the most expensive part of the migration?

Two things tied: the _app.tsx and _document.tsx rewrite (because everything global lives there) and the long tail of third-party library hydration mismatches. The first is a fixed 1 to 3 day cost. The second is variable and can balloon a 10-week migration to 14 weeks if you have a UI-heavy app. Audit your package.json first.

Should I hire a full-time engineer or book on-demand for this?

If you do not already have App Router experience in-house, on-demand makes more sense. The migration is a fixed-scope, time-bounded project; once it ships, you do not need that headcount permanently. Booking a senior engineer through Cadence at $1,500/week for 10 weeks costs $15,000. Hiring a US senior engineer is $200k+/year fully loaded, plus 3 to 4 months of recruiting time. For comparable database migrations like Postgres to MySQL moves, we recommend the same on-demand approach for the same reason.

All posts