How should I adopt React 19 in Next.js 15?

React 19 is required by Next.js 15 App Router, and its server-first defaults introduce breaking changes: cookies, headers, params, and searchParams are now async; fetch and GET Route Handlers are uncached by default; useFormState is replaced by useActionState; and ssr: false is disallowed in Server Components. Teams migrating from Next.js 14 or Remix 2 must refactor for these server-first defaults. Note: 'Remix 3' has dropped React entirely; the React-ecosystem successor to Remix 2 is React Router v7.

Upgrade with official codemods if all dependencies support React 19. Use UnsafeUnwrapped shims for staged migration. React Router v7 if you want loaders/actions without RSC.

Blockers

Who this is for

Candidates

Upgrade Next.js 14 → 15 using official codemods with full React 19 adoption

Next.js 15 (stable since October 2024) requires React 19 for the App Router and ships an automated upgrade CLI (`npx @next/codemod@canary upgrade latest`) that handles the majority of breaking changes, including async Request APIs, cache default changes, and hook replacements.

When to choose

Best for serverless + small-team or serverless + low-ops environments where the App Router is already the primary router and the codebase has good test coverage. Choose this when you want a single well-bounded upgrade event and can validate the changed caching defaults (fetch, GET routes, client router cache) and async API shapes (params, cookies, headers) before shipping.

Tradeoffs

The codemod handles mechanical changes — async params/cookies/headers, renaming useFormState to useActionState, removing experimental-edge runtime — but caching semantic changes require manual review: fetch requests and GET Route Handlers are now uncached by default, and client-side Page segments are no longer cached during navigation. Server Actions now use unguessable IDs and dead-code-eliminate unused exports. The Pages Router retains React 18 compatibility in Next.js 15, but mixing App Router (React 19) and Pages Router (React 18) in the same app is officially not recommended.

Cautions

Do not skip validating caching behavior after migration: applications that previously relied on Next.js 14 default caching for fetch or GET routes will see increased server load and potentially stale-data regressions. The react-server condition is now enforced in Middleware, which blocks client-only React imports in that layer. next/dynamic with ssr: false is now disallowed in Server Components — convert affected components to Client Components first.

Staged Next.js 15 migration using UnsafeUnwrapped compatibility shims

Next.js 15 provides temporary synchronous-access shims (UnsafeUnwrappedCookies, UnsafeUnwrappedHeaders, UnsafeUnwrappedDraftMode) that emit dev/prod warnings, allowing teams to separate the framework upgrade PR from the async API refactor PRs.

When to choose

Best for enterprise + monorepo teams with large App Router codebases where running all codemods and async refactors in a single change is high-risk. Use this when you need the Next.js 15 framework upgrade to land on a fast timeline (e.g., to unlock security patches or Turbopack dev stability) while spreading the async API migration across follow-up work items.

Tradeoffs

Shims reduce the blast radius of the initial upgrade by keeping synchronous access patterns temporarily working. They do not require codemod output to be correct before merging. The cost is ongoing warning noise in logs and a known technical debt backlog of async conversions that must be cleared before the next major Next.js version removes the shims.

Cautions

The UnsafeUnwrapped types are explicitly named 'Unsafe' in the API surface — treat them as temporary scaffolding only. Leaving shims in production indefinitely will mask future deprecation warnings and increase migration cost at the next major. Establish a concrete deadline for clearing all shim usages as part of the upgrade plan.

Migrate Remix 2 → React Router v7 (stable, loaders/actions without RSC)

Remix 2 features — loaders, actions, route-based data fetching — have been merged directly into React Router v7, which supports React 19. This is the stable, officially maintained migration path for Remix 2 users. React Server Components on React Router are available only as an unstable preview (using Parcel, not Vite) and are not yet production-recommended.

When to choose

Best for small-team + low-ops or cost-sensitive teams migrating away from Remix 2 who want React 19 support without taking on RSC complexity. React Router v7's loaders and actions already provide a server-first data model without requiring the bundler-level infrastructure that RSC demands. Choose this when Vite is your bundler and you cannot yet adopt Parcel for RSC support.

Tradeoffs

React Router v7 gives you the full Remix 2 feature set under a new package name, with React 19 support and no forced RSC adoption. The trade-off is that RSC-specific capabilities (async server components, streaming RSC format, server-only component trees) are not available on the stable path. The RSC preview exists and allows incremental adoption alongside existing client routes, but requires Parcel and carries no stability guarantee.

Cautions

Important: 'Remix 3' is a separate, unrelated project that has dropped React entirely and rebuilt on web standards. Teams in the React ecosystem should migrate to React Router v7, not to Remix 3. The React Router team has explicitly stated as of this writing: 'React Router RSC is still unstable, so we currently recommend using the existing Framework Mode or data/declarative APIs.' Do not use the RSC preview in production.

Facts updated: 2026-03-16
Published: 2026-03-29

Try with your AI agent

$ npm install -g pocketlantern
$ pocketlantern init
# Restart Claude Code, Cursor, or your MCP client, then ask:
# "How should I adopt React 19 in Next.js 15?"
Missing something? Request coverage