Node.js 18.17 or newer is required
Action requiredOlder Node.js runtimes are unsupported.
Update local, CI and hosting runtimes before building.
Compare Next.js versions and see exactly what changes, what requires action, and what you can start using.
UpgradePath detects relevant tools and selects them automatically.
Select the tools in your project to include relevant dependency updates in this guide.
Older Node.js runtimes are unsupported.
Update local, CI and hosting runtimes before building.
Static export is configured through output.
// build: next build && next export
module.exports = {};// build: next build
module.exports = {
output: 'export',
};Set output: 'export' in next.config.js and run next build. Check dynamic routes and server-only features.
Use the built-in font module.
import { Roboto } from '@next/font/google';
const font = Roboto({ weight: '400', subsets: ['latin'] });import { Roboto } from 'next/font/google';
const font = Roboto({ weight: '400', subsets: ['latin'] });Replace @next/font imports with next/font; run npx @next/codemod@latest built-in-next-font .
The next/server import is replaced.
import { ImageResponse } from 'next/server';
export async function GET() {
return new ImageResponse(<div>UpgradePath</div>);
}import { ImageResponse } from 'next/og';
export async function GET() {
return new ImageResponse(<div>UpgradePath</div>);
}Import ImageResponse from next/og and verify generated social images.
cookies, headers, draftMode, params and searchParams require migration.
import { cookies } from 'next/headers';
type Props = { params: { slug: string } };
export default function Page({ params }: Props) {
const theme = cookies().get('theme')?.value;
return <main data-theme={theme}>{params.slug}</main>;
}import { cookies } from 'next/headers';
type Props = { params: Promise<{ slug: string }> };
export default async function Page({ params }: Props) {
const { slug } = await params;
const store = await cookies();
const theme = store.get('theme')?.value;
return <main data-theme={theme}>{slug}</main>;
}Await request APIs and route props in App Router code. Run npx @next/codemod@latest next-async-request-api . and review its output.
React dependencies and types need coordinated updates.
{
"dependencies": {
"next": "^14.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}{
"dependencies": {
"next": "^15.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}Upgrade react and react-dom together. For TypeScript, update their types and check third-party peer dependencies.
Server fetch calls no longer opt into caching automatically.
// Next.js 14: cache-eligible server request
const response = await fetch('https://example.com/api/catalog');// Next.js 15: opt in if this catalog should remain cached
const response = await fetch('https://example.com/api/catalog', {
cache: 'force-cache',
});Use cache: 'force-cache' explicitly where caching is intended; check freshness and SSR performance.
GET responses no longer default to cached output.
// app/api/catalog/route.ts
export async function GET() {
return Response.json({ categories: ['books', 'music'] });
}// Only for public data intended to be statically cached.
export const dynamic = 'force-static';
export async function GET() {
return Response.json({ categories: ['books', 'music'] });
}Opt eligible handlers into static caching with export const dynamic = 'force-static'.
Client navigation changes page cache reuse.
// next.config.mjs
// Next.js 14 page cache defaults
export default {};// Optional: reuse dynamic page segments for 30 seconds.
export default {
experimental: {
staleTimes: { dynamic: 30 },
},
};Review navigation and staleTimes configuration; test back/forward behavior.