# Next.js 15 Upgrade Guide ## Overview This guide provides comprehensive instructions for upgrading from Next.js 13 to Next.js 15, covering breaking changes, new features, and migration strategies for professional developers. ## Quick Start ### Automated Upgrade (Recommended) ```bash npx @next/codemod@canary upgrade latest ``` ### Manual Upgrade ```bash npm install next@latest react@latest react-dom@latest # or with force flag if peer dependency warnings npm install next@latest react@latest react-dom@latest --force ``` ## Breaking Changes ### 1. Async Request APIs ⚠️ **CRITICAL** APIs like `cookies()`, `headers()`, `draftMode()`, `params`, and `searchParams` are now async. **Before (Next.js 13):** ```typescript // layout.tsx, page.tsx, route.ts export default function Page({ params, searchParams }) { const cookieStore = cookies(); const headersList = headers(); // ... } ``` **After (Next.js 15):** ```typescript // layout.tsx, page.tsx, route.ts export default async function Page({ params, searchParams }) { const cookieStore = await cookies(); const headersList = await headers(); const resolvedParams = await params; const resolvedSearchParams = await searchParams; // ... } ``` **Codemod Available:** ```bash npx @next/codemod@canary next-async-request-api . ``` ### 2. Runtime Configuration **Before:** ```javascript export const runtime = 'experimental-edge'; ``` **After:** ```javascript export const runtime = 'edge'; ``` ### 3. Font Imports **Before:** ```typescript import { Inter } from '@next/font/google'; ``` **After:** ```typescript import { Inter } from 'next/font/google'; ``` ### 4. Geolocation in NextRequest **Before:** ```typescript // middleware.ts export function middleware(request: NextRequest) { const { geo, ip } = request; // ... } ``` **After:** ```typescript import { geolocation, ipAddress } from '@vercel/functions'; export function middleware(request: NextRequest) { const geo = geolocation(request); const ip = ipAddress(request); // ... } ``` ## New Caching Semantics ### Default Behavior Changes - `fetch` requests are **uncached by default** (was cached) - GET Route Handlers are **uncached by default** - Client navigations are **uncached by default** ### Opt-in to Caching ```typescript // Force static caching for specific routes export const dynamic = 'force-static'; // Or configure in next.config.ts const nextConfig = { experimental: { staleTimes: { dynamic: 30, // 30 seconds static: 180, // 3 minutes }, }, }; ``` ## New Features ### 1. React 19 Support - App Router uses React 19 RC - Pages Router remains on React 18 for compatibility - React Compiler support (experimental) ```typescript // next.config.ts const nextConfig = { experimental: { reactCompiler: true, }, }; ``` ### 2. Turbopack for Development (Stable) ```bash # 76.7% faster local server startup # 96.3% faster code updates with Fast Refresh # 45.8% faster initial route compile next dev --turbo ``` ### 3. Static Route Indicator Visual indicator in development to identify static vs dynamic routes. ```typescript // next.config.ts - to disable const nextConfig = { devIndicators: { appIsrStatus: false, }, }; ``` ### 4. `unstable_after` API (Experimental) Schedule work after response completion: ```typescript import { unstable_after as after } from 'next/server'; export default function Layout({ children }) { after(() => { // This runs after the response is sent console.log('Logged after response'); }); return <>{children}; } ``` Enable in config: ```typescript // next.config.ts const nextConfig = { experimental: { after: true, }, }; ``` ### 5. Enhanced `
` Component ```typescript import Form from 'next/form'; export default function SearchForm() { return (
); } ``` ### 6. Instrumentation.js (Stable) ```typescript // instrumentation.ts export function onRequestError(err, request, context) { console.error('Request error:', err, request.url); } ``` ### 7. Self-Hosting Improvements ```typescript // next.config.ts const nextConfig = { // Configure ISR expiration (default: 1 year) expireTime: 60 * 60 * 24 * 30, // 30 days }; ``` ### 8. Security Enhancements - Server Actions now have secure, unguessable IDs - Dead code elimination for unused Server Actions - Treated as public HTTP endpoints ### 9. Bundling Optimization ```typescript // next.config.ts const nextConfig = { // App Router: external packages bundled by default serverExternalPackages: ['package-to-exclude'], // Pages Router: opt-in bundling bundlePagesRouterDependencies: true, transpilePackages: ['package-to-bundle'], }; ``` ### 10. ESLint 9 Support ```bash # Migrate to flat config ESLINT_USE_FLAT_CONFIG=false npm run lint ``` ## Migration Checklist ### Pre-Migration - [ ] Backup your project - [ ] Review breaking changes - [ ] Update TypeScript types: `@types/react@latest @types/react-dom@latest` - [ ] Test in development environment ### During Migration - [ ] Run automated upgrade: `npx @next/codemod@canary upgrade latest` - [ ] Update async request APIs (use codemod) - [ ] Fix runtime configurations - [ ] Update font imports - [ ] Handle geolocation changes - [ ] Review caching behavior ### Post-Migration - [ ] Test all routes and functionality - [ ] Enable Turbopack: `next dev --turbo` - [ ] Configure new caching semantics - [ ] Explore React 19 features - [ ] Update ESLint configuration - [ ] Performance testing ## Common Issues & Solutions ### 1. Peer Dependency Warnings ```bash npm install --legacy-peer-deps # or npm install --force ``` ### 2. TypeScript Errors with Async APIs Ensure all request API calls are awaited and functions are marked async. ### 3. Caching Behavior Changes If experiencing performance issues, opt-in to caching: ```typescript export const dynamic = 'force-static'; ``` ### 4. React 19 Compatibility Some third-party packages may not be React 19 compatible yet. Consider: - Checking package compatibility - Using Pages Router for problematic components - Waiting for package updates ## Performance Improvements ### Development - **Turbopack**: 76.7% faster server startup - **Fast Refresh**: 96.3% faster code updates - **Route Compilation**: 45.8% faster initial compile ### Production - **Bundle Optimization**: Automatic external package bundling - **Security**: Enhanced Server Actions with dead code elimination - **Caching**: More predictable caching behavior ## Resources ### Official Documentation - [Next.js 15 Upgrade Guide](https://nextjs.org/docs/app/guides/upgrading/version-15) - [Next.js 15 Blog Post](https://nextjs.org/blog/next-15) - [React 19 Upgrade Guide](https://react.dev/blog/2024/04/25/react-19-upgrade-guide) ### Tools & Codemods - [Next.js Codemods](https://nextjs.org/docs/app/building-your-application/upgrading/codemods) - [Turbopack Documentation](https://nextjs.org/docs/app/api-reference/next-config-js/turbo) ### Community Resources - [Migration Examples](https://github.com/leerob/next-saas-starter/pull/62) - [ESLint 9 Migration](https://eslint.org/docs/latest/use/migrate-to-9) ## Summary Next.js 15 represents a significant evolution with: - **Async Request APIs** requiring code changes - **Improved caching semantics** with opt-in behavior - **React 19 support** with new features - **Turbopack stability** for faster development - **Enhanced security** and performance optimizations The upgrade process is well-supported with automated tools and codemods, making the transition manageable for most projects. Focus on testing async API changes and reviewing caching behavior for the smoothest upgrade experience.