Next.js 15 ships several features that have been in beta or canary for over a year. The most significant: Partial Prerendering (PPR) is now stable, Turbopack is stable for both development and production builds, and the request-time APIs are now async. Here's what changed and what you need to update.
Partial Prerendering (PPR) — stable
PPR is the biggest architectural addition. It splits a page into two parts at build time:
- Static shell — layout, navigation, above-the-fold structure. Generated at build time and served instantly from the CDN edge.
- Dynamic holes — content wrapped in
<Suspense>that contains dynamic data. Streamed from the server after the static shell is delivered.
The result: static site performance for the shell (instant CDN delivery), server rendering for the dynamic parts (fresh data), all in a single round trip.
Enable PPR per-page:
export const experimental_ppr = true;
Or globally in next.config.js:
experimental: { ppr: true }
Turbopack for production builds
Turbopack (Next.js's Rust-based bundler) is now stable for production builds. Enable it with:
next build --turbopack
Benchmark improvements on large codebases:
| Metric | Webpack | Turbopack |
|---|---|---|
| Dev server cold start | 45 s | 3 s |
| HMR update | 2–5 s | ~50 ms |
| Production build | 4 min | 90 s |
Async request APIs
In Next.js 15, the APIs for accessing request-time data are now async. This is a breaking change from Next.js 14:
// Next.js 14 (sync)
const { id } = params;
const { token } = cookies();
// Next.js 15 (async)
const { id } = await params;
const cookieStore = await cookies();
const token = cookieStore.get('token');
Affected APIs: params, searchParams, cookies(), headers(), draftMode().
Run the migration codemod to update existing code:
npx @next/codemod@canary next-async-request-api .
Improved caching semantics
Next.js 15 reverses the aggressive default caching behavior introduced in Next.js 13/14. In Next.js 15:
fetch()requests are not cached by default (was: cached indefinitely)GETRoute Handlers are not cached by default (was: cached)- Client Router Cache does not reuse stale page segments by default (was: reused for 30 seconds)
Opt into caching explicitly with fetch(url, { cache: 'force-cache' }) or route segment config.
React 19 integration
Next.js 15 ships with React 19 support. Key React 19 additions you can use:
- Actions — async functions passed to form actions, with built-in pending state, error handling, and optimistic updates.
use()hook — reads context and promises inside render.- ref as prop — no more
forwardRefwrapper.
Migration notes
The async request API change will cause runtime errors on any page that accesses cookies(), headers(), or params synchronously. Run the codemod first, then test each route. The Next.js 15 upgrade guide covers edge cases for middleware and nested layouts.