Loading...
Loading...
Structured workflow for upgrading Next.js applications across major versions. Use when migrating a Next.js project from one major version to another (e.g., 13 to 14, 14 to 15, 15 to 16). Covers codemod automation, breaking change detection, incremental migration paths, and post-upgrade validation.
npx skill4agent add oimiragieo/agent-studio next-upgrade# Check current version
cat package.json | grep '"next"'
# Check Node.js version (Next.js 15+ requires Node 18.18+, Next.js 16 requires Node 20+)
node --version| Next.js | Minimum Node.js | Minimum React |
|---|---|---|
| 13 | 16.14 | 18.2.0 |
| 14 | 18.17 | 18.2.0 |
| 15 | 18.18 | 19.0.0 |
| 16 | 20.0 | 19.0.0 |
git checkout -b upgrade/nextjs-{target-version}# Interactive mode (recommended) -- selects applicable codemods
npx @next/codemod@latest upgrade latest
# Or target a specific version
npx @next/codemod@latest upgrade 15
npx @next/codemod@latest upgrade 16next-image-to-legacy-imagenext/imagenext/legacy/imagenext-image-experimentalnext/legacy/imagenext/imagemetadatanext-async-request-apiscookies()headers()paramssearchParamsnext-dynamic-ssr-falsessr: false{ loading }next/dynamicnext-og-importnext/ognext-use-cacheunstable_cache'use cache'next-cache-lifecacheLife()next-form<form>next/form# Update Next.js and React together
npm install next@latest react@latest react-dom@latest
# For Next.js 15+, also update React types
npm install -D @types/react@latest @types/react-dom@latest
# Update eslint config
npm install -D eslint-config-next@latest--legacy-peer-depsnext.config.jsnext.config.ts// next.config.ts (Next.js 15+ recommends TypeScript config)
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
// Next.js 15+: experimental features that graduated
// Remove these from experimental:
// - serverActions (now stable in 14+)
// - appDir (now stable in 14+)
// - ppr (now stable in 16+)
// Next.js 16+: new cache configuration
cacheComponents: true, // Enable component-level caching
};
export default nextConfig;| Version | Change |
|---|---|
| 14 | |
| 14 | |
| 15 | |
| 15 | |
| 16 | |
| 16 | |
cookies()headers()paramssearchParams// Before (Next.js 14)
export default function Page({ params }: { params: { id: string } }) {
const { id } = params;
}
// After (Next.js 15+)
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
}fetch()// Before: cached by default
fetch('https://api.example.com/data');
// After: explicitly opt-in to caching
fetch('https://api.example.com/data', { cache: 'force-cache' });
// Or use 'use cache' directive in Next.js 16// Next.js 15+: explicitly set caching
export const dynamic = 'force-static';# Run existing test suite
npm test
# Run build to catch compile-time errors
npm run build
# Run dev server and check key pages manually
npm run dev# Regenerate TypeScript declarations
npm run build
# Fix any new type errors
npx tsc --noEmitPagePropsMetadataNextRequestNextResponse# Create detailed commit
git add -A
git commit -m "chore: upgrade Next.js from {old} to {new}
Breaking changes resolved:
- [list specific changes]
Codemods applied:
- [list codemods run]
Manual fixes:
- [list manual changes]"Next.js 13 -> 14 -> 15 -> 16.nextrm -rf .nextrm -rf node_modules && npm installrm -rf .next/cacheNextResponse.rewrite()--legacy-peer-deps| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
| Upgrading on the main branch directly | Half-migrated code can reach production; rollback requires a revert commit | Always create |
| Skipping intermediate versions | Version-specific codemods are not composable; skipped breaking changes cause runtime failures | Upgrade one major version at a time: 13→14→15→16; commit a checkpoint at each step |
| Manual migration before running codemods | Creates divergence from codemod output; codemods cannot merge cleanly with manual edits | Run codemods first; apply manual fixes only for patterns codemods could not handle |
Using | Hidden version conflicts cause runtime failures not visible at install time | Resolve conflicts explicitly; use the flag only with a documented justification |
| Validating only in dev mode | Dev server skips SSG, edge runtime, and build optimizations that can fail post-upgrade | Run |