> **TL;DR.** Next.js 16 ships with the App Router as the only supported model, React 19 as the baseline, and first-class Partial Prerendering that eliminates most SSR vs. static tradeoffs. If you're starting a new project in 2026, this is the stack. If you're on Pages Router, the migration path is well-documented and worth doing.

---

What Actually Changed in Next.js 16

The headline feature is **Partial Prerendering (PPR) going stable**. PPR lets a single route serve a static shell instantly from the CDN while streaming dynamic slots in the same HTTP response — no per-route `export const dynamic = 'force-dynamic'` juggling.

Key changes from Next.js 14/15:

  • **Pages Router is deprecated** — still works but receives no new features
  • **React 19 required** — `use()`, `useOptimistic()`, and the Actions model are first-class
  • **Turbopack is the default bundler** — `next dev` uses Turbopack; `next build` does too (stable since 15.3)
  • **`after()` API stable** — run work after a response has flushed (logging, analytics, cache invalidation) without blocking the user
  • **`forbidden()` and `unauthorized()` APIs** — throw these from Server Components to render dedicated error boundaries instead of generic 500s
  • **Node.js 20+ required** — drop Node 18 from your CI/CD

---

App Router Mental Model

The App Router uses the file system to declare rendering behavior, not runtime configuration.

**Directory conventions you must know:**

**Server vs. Client Components:**

  • Everything is a Server Component by default. They run on the server, access databases directly, and never ship their source to the browser.
  • Add `"use client"` at the top of a file when you need browser APIs, event handlers, or React state.
  • The rule: push `"use client"` as far down the tree as possible. A page can be a Server Component while a single button inside it is a Client Component.

---

Data Fetching in 2026

Forget `getServerSideProps` and `getStaticProps` — those are Pages Router concepts.

**Fetch in Server Components:**

```ts

// app/products/page.tsx

async function ProductsPage() {

const products = await fetch('https://api.example.com/products', {

next: { revalidate: 3600 } // ISR: revalidate every hour

}).then(r => r.json())

return <ProductList products={products} />

}

```

**On-demand revalidation with Server Actions:**

```ts

'use server'

import { revalidatePath } from 'next/cache'

export async function publishPost(id: string) {

await db.posts.update(id, { published: true })

revalidatePath('/blog')

}

```

**When to use what:**

  • Static data with periodic refresh → `fetch` + `next.revalidate`
  • Data specific to the current user → `fetch` with `cache: 'no-store'` or `noStore()`
  • Mutations → Server Actions with `revalidatePath` or `revalidateTag`
  • Real-time → route handler + SSE, or a client-side WebSocket

---

Server Actions Replace Most API Routes

Server Actions let client components call server-side functions directly without writing a separate API endpoint.

```ts

// app/actions.ts

'use server'

export async function createComment(formData: FormData) {

const text = formData.get('text') as string

await db.comments.insert({ text, userId: await getAuthUser() })

revalidatePath('/posts')

}

```

```tsx

// Client component

<form action={createComment}>

<input name="text" />

<button type="submit">Post</button>

</form>

```

With React 19's `useActionState`, you get pending state and error handling with minimal boilerplate. API routes (`app/api/`) are still useful when you need an endpoint consumed by external clients, mobile apps, or third-party webhooks.

---

Partial Prerendering: The Architecture Shift

PPR is the biggest architectural change in Next.js 16 complete picture. It lets one route combine:

1. A **static shell** prerendered at build time and served from CDN edge

2. **Dynamic holes** that stream in after the shell is delivered

Enable it:

```ts

// next.config.ts

export default {

experimental: {

ppr: true,

},

}

```

Mark dynamic parts with `Suspense`:

```tsx

import { Suspense } from 'react'

import { UserCart } from './user-cart' // reads cookies → dynamic

export default function ShopPage() {

return (

<main>

<StaticHero /> {/* static, prerendered */}

<Suspense fallback={<CartSkeleton />}>

<UserCart /> {/* dynamic, streams in */}

</Suspense>

</main>

)

}

```

Without PPR, reading a cookie in any component on the page forces the entire route to be dynamic. PPR eliminates that penalty.

---

TypeScript and Config Setup

Next.js 16 ships with a typed config file by default:

```ts

// next.config.ts (not .js)

import type { NextConfig } from 'next'

const config: NextConfig = {

images: {

remotePatterns: [{ hostname: 'cdn.example.com' }],

},

experimental: {

ppr: true,

},

}

export default config

```

**Strict TypeScript setup worth enabling:**

```json

// tsconfig.json

{

"compilerOptions": {

"strict": true,

"noUncheckedIndexedAccess": true,

"paths": {

"@/*": ["./src/*"]

}

}

}

```

`noUncheckedIndexedAccess` catches array index bugs that strict mode misses. Enable it on new projects; retrofit carefully on existing ones.

---

Performance Checklist

Before deploying to production, verify:

  • `next build` output table shows no route unexpectedly large (>200KB first load JS)
  • Dynamic imports (`next/dynamic`) used for heavy client components
  • `next/image` wrapping every `<img>` — automatic WebP/AVIF conversion, lazy loading, CLS prevention
  • `next/font` for all fonts — self-hosted, zero layout shift
  • `Suspense` boundaries placed above any component that fetches data
  • `generateStaticParams` used for dynamic routes with known IDs (PDPs, blog posts)

Run `npx @next/bundle-analyzer` to visualize what's in your bundles. The common offender: a charting library imported in a Server Component that should be client-only.

---

Deploying Next.js 16

**Vercel (zero config):**

```bash

vercel --prod

```

Vercel natively supports PPR, ISR, edge middleware, and Server Actions with no additional configuration.

**Self-hosted (Node.js server):**

```bash

next build

outputs .next/ folder

node server.js # or: next start

```

Self-hosting loses automatic edge cache invalidation — you need a CDN in front and manual purge calls. Vercel, Netlify, and Cloudflare Workers all support Next.js to varying degrees; check PPR support specifically if you use it.

**Docker:**

```dockerfile

FROM node:20-alpine AS builder

WORKDIR /app

COPY . .

RUN npm ci && npm run build

FROM node:20-alpine

WORKDIR /app

COPY --from=builder /app/.next/standalone ./

CMD ["node", "server.js"]

```

Enable `output: 'standalone'` in `next.config.ts` to get a minimal production bundle.

---

When to Use Next.js vs. Alternatives

Next.js 16 is the right choice when:

  • You need a mix of static, ISR, and dynamic routes in one project
  • Your team already knows React
  • You're deploying to Vercel and want zero infra management
  • You're building an AI-powered app where server-side API calls should never expose keys to the browser — relevant if you're following patterns from the [AI for Backend Developers guide](/en/rehberler/ai-backend-developers-2026)

Consider alternatives when:

  • **Pure static site** — Astro is simpler and ships less JS
  • **Full-stack Python/Go backend** — Next.js as a thin frontend calling your existing API is fine, but a dedicated Next.js full-stack might be overkill
  • **Offline-first mobile** — React Native or a PWA wrapper

For [vibe coding e-commerce](/en/rehberler/vibe-coding-ecommerce-2026) projects, Next.js + Vercel is the dominant stack because PPR handles the static catalog / dynamic cart split out of the box.

---

Next Steps

The nextjs 16 complete stack pairs well with a few adjacent decisions:

  • **AI integration:** Server Components make it trivial to call AI APIs server-side without exposing keys. See the [How to Start AI SaaS guide](/en/rehberler/how-to-start-ai-saas-2026) for patterns.
  • **Internal tooling:** If you're building dashboards and admin panels, the [Vibe Coding for Internal Tools guide](/en/rehberler/vibe-coding-internal-tools-2026) covers auth, role-based access, and data table patterns.
  • **Agent UIs:** Streaming Server Components pair naturally with LLM streaming responses. The [Vibe Coding for AI Agents guide](/en/rehberler/vibe-coding-ai-agents-2026) covers frontend patterns for agent applications.

Migrate from Pages Router incrementally: both routers coexist in one project, so you can move route by route rather than rewriting everything at once. Start with the routes that need PPR or Server Actions first — those see the most immediate benefit.

All guides

Related guides