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.

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

Migration Steps

npm install next@16 react@19 react-dom@19

Thanks for reading!

Read More Articles