
Key Takeaways
- 1What changed in Next.js 16?
- 2Step 1: check Node.js, TypeScript and browser targets
- 3Step 2: run the upgrade codemod
- 4Step 3: make request APIs async
- 5Step 4: rename middleware to proxy and fix removed features
Quick Answer
Next.js 16, released on 21 October 2025, makes Turbopack the default bundler, introduces opt-in Cache Components with the use cache directive, stabilises React Compiler support, ships with React 19.2 features, and renames middleware.ts to proxy.ts. Before upgrading, move to Node.js 20.9 or later, convert any synchronous params, cookies and headers access to async, replace next lint, and check image defaults. Run the official codemod first; most business apps need 2 to 10 developer days.
This checklist is for developers and technical leads who run a Next.js 14 or 15 application in production and need to plan the move to Next.js 16. It lists the breaking changes in the order you will meet them, shows the code changes with short examples, and ends with a decision table so you can estimate effort and choose when to adopt optional features such as Cache Components and the React Compiler.
What changed in Next.js 16?
Next.js 16 changed the default bundler to Turbopack, added an explicit opt-in caching model called Cache Components, made React Compiler support stable, adopted React 19.2 features, and replaced middleware with proxy, alongside several removals of long-deprecated APIs.
| Area | Next.js 16 change | Action needed |
|---|---|---|
| Bundler | Turbopack is the default for dev and build | Test the build; use the webpack flag only if a custom config blocks you |
| Caching | Cache Components and use cache, fully opt-in | Optional; plan separately |
| Middleware | middleware.ts deprecated, proxy.ts runs on Node.js | Rename file and function |
| Request APIs | Sync access to params, searchParams, cookies, headers removed | Await them |
| Runtime versions | Node.js 20.9+, TypeScript 5.1+ | Update servers and CI |
| Linting | next lint command removed | Run ESLint or Biome directly |
| Images | New defaults for cache TTL, qualities, sizes, redirects | Review next.config images block |
| Cache APIs | revalidateTag needs a cacheLife profile; new updateTag and refresh | Update calls |
The primary source is the Next.js 16 release post, with details in the version 16 upgrade guide on nextjs.org.
Step 1: check Node.js, TypeScript and browser targets
Next.js 16 requires Node.js 20.9 or later and TypeScript 5.1 or later, and targets Chrome, Edge and Firefox 111 and above plus Safari 16.4 and above, so confirm your servers, CI images and analytics before touching code.
Node.js 18 is no longer supported. On shared hosting or managed Node environments, the server Node version is often older than developer laptops; check it first, because a failed deploy at the end of a migration is the most avoidable delay. If your analytics show meaningful traffic from older browsers, decide now whether that is acceptable.
Step 2: run the upgrade codemod
Start with the official upgrade codemod, which updates packages and applies many mechanical changes automatically, then review the diff file by file rather than trusting it blindly, because some patterns cannot be migrated automatically.
npx @next/codemod@canary upgrade latest
# or upgrade packages manually
npm install next@latest react@latest react-dom@latest
If you are on Next.js 14, consider stepping to the latest 15 release first, fixing its warnings, and only then moving to 16. Two smaller jumps are easier to debug than one large one, and the warnings in 15 point at most of the code that 16 will reject.
Do this on a branch, commit the codemod output as its own commit, and keep manual fixes in separate commits. Review becomes far easier.
Step 3: make request APIs async
Synchronous access to params, searchParams, cookies, headers and draftMode was removed in Next.js 16, so every page, layout, route handler and metadata function that reads them must await the value before use.
Next.js 15 allowed synchronous access with warnings; version 16 does not. A typical page change:
// Before (Next.js 14 style)
export default function Page({ params }) {
return <h1>{params.slug}</h1>;
}
// After (Next.js 16)
export default async function Page({ params }) {
const { slug } = await params;
return <h1>{slug}</h1>;
}
Also check generateMetadata, opengraph-image and other metadata image routes, which now receive async params too.
Step 4: rename middleware to proxy and fix removed features
Rename middleware.ts to proxy.ts and the exported function to proxy, keeping the logic the same, then work through the removals: next lint, AMP, runtime config objects, experimental PPR flags and the old turbopack config location.
// proxy.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export default function proxy(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url));
}
proxy.ts runs on the Node.js runtime. The middleware.ts file still works for Edge runtime cases but is deprecated. Other items on the removal list:
- next lint: removed, and next build no longer lints. Change the lint script to call ESLint directly; a codemod exists for this.
- serverRuntimeConfig and publicRuntimeConfig: removed; use environment variables.
- experimental.turbopack: moved to a top-level turbopack key.
- experimental.dynamicIO: renamed to cacheComponents; experimental.ppr removed.
- Parallel routes: every slot now needs an explicit default.js or the build fails.
- Smooth scrolling: no longer automatic; add data-scroll-behavior to the html element to keep it.
Step 5: review image and caching behaviour
Next.js 16 changed image defaults, including a four-hour minimum cache TTL, a default quality of 75 and a three-redirect cap, and revalidateTag now takes a cacheLife profile.
Images
If you set explicit values in next.config, they still win. If you relied on defaults, check product photos where you passed custom quality values, because quality is now coerced to the nearest allowed value. Local images with query strings need images.localPatterns. images.domains is deprecated in favour of remotePatterns.
Cache APIs
import { revalidateTag, updateTag } from 'next/cache';
// Stale-while-revalidate for content that can lag briefly
revalidateTag('blog-posts', 'max');
// In a Server Action, when the user must see their own change at once
updateTag('user-' + userId);
The new refresh function, also limited to Server Actions, refreshes uncached data on the page without touching the cache, which suits counters and notification badges.
The single-argument form of revalidateTag is deprecated. Search the codebase for every call and decide which behaviour each needs.
Should you turn on Cache Components and the React Compiler?
Treat both as separate projects after the upgrade: Cache Components and use cache change how you think about caching and are fully opt-in, and the React Compiler is stable but off by default and increases build times.
Cache Components make caching explicit: dynamic code runs at request time by default, and you mark pages, components or functions with the use cache directive to cache them. Enable it with cacheComponents set to true in next.config. It is the right long-term model, but it touches every data-fetching path, so schedule it as its own sprint with performance measurements before and after.
The React Compiler memoises components automatically. Enable it with reactCompiler set to true and the babel-plugin-react-compiler package. Expect higher compile times because it relies on Babel. Try it on a branch and compare render counts and build times on your heaviest pages before committing.
Our own upgrade path from Next.js 15
Our own jktechhub.com runs on Next.js 15 with the App Router behind a custom Node server, and our upgrade audit found four tasks: the hosting Node version, the next lint script, async params on dynamic routes, and image settings.
What the audit showed, as an example of how small a typical business site's list can be:
- No middleware file, because redirects live in next.config, so the proxy rename does not apply.
- The lint script calls next lint, which must change to ESLint directly.
- Dynamic routes for blog posts, country pages and services already await params, a habit worth adopting on 15 before you upgrade.
- Images already use remotePatterns and an explicit minimumCacheTTL, so the new defaults change nothing for us.
- Hosting Node version is the item to confirm with the host before the deploy.
The lesson for other teams: the cheapest time to prepare is while still on 15. Awaiting params, moving redirects into config and replacing deprecated image settings can all be done before the version bump, which shrinks the upgrade itself to a short, low-risk change.
For client applications with authentication, dashboards and Server Actions, our estimates so far run from 2 developer days for a marketing site to about 10 for a large app with many route handlers and custom webpack configuration.
Next.js 16 migration checklist and effort estimate
Use this checklist in order, tick each item on a branch, and estimate effort from the number of dynamic routes, route handlers, custom webpack rules and cache invalidation calls in your codebase.
| Item | Check | Typical effort |
|---|---|---|
| Node.js 20.9+ on servers and CI | node -v on every environment | Hours |
| Codemod run and reviewed | Separate commit | Half a day |
| Async params, searchParams, cookies, headers | Search for each API | Half a day to 3 days |
| middleware.ts to proxy.ts | Rename and test redirects | Hours |
| Lint script without next lint | CI passes | Hours |
| Turbopack build passes | Custom webpack rules ported or flagged | Hours to 3 days |
| Image config reviewed | Visual check of key pages | Hours |
| revalidateTag calls updated | Each has a profile or uses updateTag | Hours to 1 day |
| Parallel routes have default.js | Build passes | Hours |
| Full regression and Core Web Vitals check | Before and after numbers | 1-2 days |
Related reading and next step
These pages cover hiring help for the upgrade, our Next.js work, and how Next.js compares with other options for content-heavy business sites that care about search traffic:
- Hire developers in India
- Next.js development services
- Hire React and Next.js developers in India
- Next.js vs WordPress for SEO
For a fixed quote on upgrading your app, send us your repository details through the contact page or WhatsApp.
Tags
Continue exploring
Pages on JK Tech Hub related to this article.
