Development
Upgrading to Next.js 16 and React 19: A Complete Migration Guide
Austin H.•November 9, 2025•10 min read
#nextjs#react#migration#typescript
Overview
Next.js 16 and React 19 bring significant improvements. This guide covers key changes, breaking updates, and migration steps.
Breaking Changes
1. React 19 Server Components
Server Components are now default. Client components need explicit marking:
'use client';
export default function MyComponent() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
2. Next.js 16 App Router
The pages/ directory is deprecated. Use app/ instead:
app/
|-- layout.tsx
|-- page.tsx
||-- api/
||-- route.ts
3. Async Server Components
Server components can now be async:
export default async function Page() {
const data = await fetch('[[API Example](https://api.example.com/data)](https://api.example.com/data));
return <div>{data}</div>;
}
Migration Steps
Step 1: Update Dependencies
npm install next@16 react@19 react-dom@19
Step 2: Create app/ Directory
mkdir -p app
touch app/layout.tsx app/page.tsx
Step 3: Convert Pages
// Before: pages/index.tsx
export default function Home() { ... }
// After: app/page.tsx
export default function Page() { ... }
Step 4: Update API Routes
// Before: pages/api/users.ts
export default function handler(req, res) { ... }
// After: app/api/users/route.ts
export async function GET(request: Request) { ... }
Common Issues
Hydration Mismatch
Server and client render differently. Use useEffect for client-only logic:
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return null;
Image Optimization
Next 16 requires explicit dimensions:
<Image src="/pic.jpg" alt="" width={640} height={480} />
Font Loading
Use the new Font API:
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
Performance Gains
- Turbopack |-- Faster builds
- Tree-shaking |-- Smaller bundles
- Image optimization |-- Better performance
- Streaming |-- Faster page loads with Suspense
Deployment
Deploy to Vercel or self-hosted:
npm run build
npm start
Timeline
- Phase 1: Update deps and fix types (1-2 days)
- Phase 2: Migrate pages to
app/(1 week) - Phase 3: Fix hydration issues (3-5 days)
- Phase 4: Optimize features (ongoing)
Resources
Take your time. Test thoroughly. The improvements are worth it.
Related Resources
- Next.js 16 Release Notes
- React 19 Blog Post
- Migration Guide - App Router
- TypeScript 5.5 Docs
- Vercel Deployment Docs
Key Takeaways
- React 19 Server Components are now default - add "use client" for interactivity
- App Router replaces pages/ directory with nested layouts
- Async Server Components enable direct data fetching in components
- Turbopack (beta) provides faster dev builds than Webpack
- Migration can be incremental - pages/ and app/ coexist
Code References
Further Reading
- Official Next.js docs: Next.js Docs
Migration Steps
npm install next@16 react@19 react-dom@19Thanks for reading!
Read More Articles