Next.js 16では、Turbopackがdev/buildともにデフォルトになり、middlewareはproxyへ改名され、params・cookies等の同期アクセスは完全に廃止されました。

本記事では、公式アップグレードガイドに沿って「codemodで自動化できる変更」と「手作業が必要な破壊的変更」を切り分けて整理します。読み終えれば、既存のNext.js 15プロジェクトを安全に16へ上げる手順がひと通り分かります。

独学に限界を感じたら

プログラミング教室がおすすめ。挫折せず最短で実力を伸ばせます。

PR

まずは全体像|Next.js 16の主な変更点

  • Turbopackが next dev / next build のデフォルトに(webpack設定が残っているとビルド失敗)
  • cookies()・headers()・params・searchParams の同期アクセスが完全廃止(await 必須)
  • middleware.ts が非推奨になり proxy.ts へ改名
  • revalidateTag は第2引数(cacheLifeプロファイル)が必須に。updateTag / refresh が新登場
  • next/image のデフォルト値が多数変更(キャッシュTTL・quality など)
  • next lint コマンド・AMPサポート・runtimeConfig が削除
  • 動作要件は Node.js 20.9以上・TypeScript 5.1以上に引き上げ

順に見ていきますが、最初に押さえたいのは移行作業の大半は公式codemodで自動化できるという点です。

アップグレード方法|codemod一発が基本

公式のアップグレードcodemodを使うと、依存の更新と主要な設定移行をまとめて実行できます。

# pnpm の場合
pnpm dlx @next/codemod@canary upgrade latest

# npm の場合
npx @next/codemod@canary upgrade latest

このcodemodは次の作業を自動化してくれます。

  • next.config の turbopack 設定を新しいトップレベル形式へ更新
  • next lint から ESLint CLI への移行
  • 非推奨になった middleware から proxy への移行
  • 安定化したAPIから unstable_ プレフィックスを除去
  • experimental_ppr のRoute Segment Configを削除

手動で上げる場合は next@latest react@latest react-dom@latest(TypeScriptなら @types/react@types/react-dom も)を更新します。

Turbopackがデフォルトに|webpack設定は要注意

Next.js 16からTurbopackが安定版となり、next devnext build の両方でデフォルトになりました。これまでの --turbopack フラグは不要です。

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

注意すべきは、カスタムwebpack設定が残っているプロジェクトでは next build が失敗することです(設定ミスを防ぐための仕様)。対応は3択です。

  • next build --turbopack で webpack 設定を無視してTurbopackでビルドする
  • webpack 設定をTurbopack互換のオプションへ移行する
  • next build --webpack でTurbopackをオプトアウトし、従来どおりwebpackでビルドする

また、これまで experimental.turbopack にあった設定はトップレベルの turbopack オプションへ昇格しました。

import type { NextConfig } from 'next'

// Next.js 16 - turbopack はトップレベルに書く
const nextConfig: NextConfig = {
  turbopack: {
    // options
  },
}

export default nextConfig

ファイルシステムキャッシュ(beta)で再起動後も速く

開発時のコンパイル成果物をディスクへ保存する experimental.turbopackFileSystemCacheForDev: true を有効にすると、devサーバー再起動後のコンパイルが大幅に速くなります。

破壊的変更①|params・cookiesの同期アクセスが完全廃止

Next.js 15で非同期化されたRequest系API(cookiesheadersdraftModeparamssearchParams)は、15の間は同期アクセスの互換モードが残っていました。16ではこの互換が完全に削除され、awaitなしでは使えません。

// app/blog/[slug]/page.tsx
export default async function Page(props: PageProps<'/blog/[slug]'>) {
  const { slug } = await props.params
  const query = await props.searchParams
  return <h1>Blog Post: {slug}</h1>
}

型の移行には npx next typegen が便利です。

PagePropsLayoutPropsRouteContext というグローバルな型ヘルパーが自動生成され、ルート文字列を渡すだけで params / searchParams に型が付きます。

opengraph-image や sitemap の生成関数に渡る params / id もPromise化されているので、あわせて await を付けてください。

破壊的変更②|middlewareはproxyへ改名

middleware というファイル名・関数名は非推奨になり、ネットワーク境界であることを明確にする proxy へ改名されました。

// middleware.ts → proxy.ts にリネームし、関数名も変更
export function proxy(request: Request) {
  // ...
}

重要な注意点として、proxy のランタイムは nodejs 固定で、edge ランタイムは使えません。edgeを使い続けたい場合は当面 middleware のままにします。

skipMiddlewareUrlNormalizeskipProxyUrlNormalize のように関連する設定フラグも改名されており、これらはcodemodが自動で書き換えます。

破壊的変更③|キャッシュAPIの刷新

revalidateTag は第2引数に cacheLife プロファイルの指定が必須になりました。従来の1引数の形は非推奨で、TypeScriptエラーになります。

// Before(Next.js 15)
revalidateTag('posts')

// After(Next.js 16)
revalidateTag('posts', 'max')

新しく updateTagrefresh も追加されました。updateTag はServer Actions専用で、キャッシュの失効と再取得を同一リクエスト内で行う「read-your-writes」(自分の変更が即座に見える)を実現します。

フォームやユーザー設定など、更新結果をすぐ見せたい場面はこちらを使います。

'use server'

import { updateTag } from 'next/cache'

export async function updateUserProfile(userId: string, profile: Profile) {
  await db.users.update(userId, profile)
  // キャッシュを失効して即時再取得。ユーザーには変更が即座に見える
  updateTag(`user-${userId}`)
}

cacheLife / cacheTag は安定化し、unstable_ プレフィックスが不要になりました。また、experimentalだったPPR(Partial Prerendering)のフラグは削除され、cacheComponents: true でオプトインする形に変わっています。

next/imageのデフォルト値が多数変更

画像最適化まわりはデフォルト値の変更が多く、静かに挙動が変わりやすいポイントです。

  • minimumCacheTTL のデフォルトが60秒から4時間へ(画像の再検証コストを削減)
  • images.qualities のデフォルトが全許可から [75] のみへ(範囲外のqualityは最も近い値に丸められる)
  • デフォルトの imageSizes から16pxが削除(srcsetの削減)
  • クエリ文字列付きのローカル画像は images.localPatterns.search の設定が必須に(列挙攻撃対策)
  • 画像リダイレクトのデフォルト上限が無制限から3回へ
  • ローカルIPへの画像最適化はデフォルトでブロック(私設ネットワークでは dangerouslyAllowLocalIP: true)
  • next/legacy/image と images.domains が非推奨(remotePatterns を使う)

その他の削除・変更点

  • next lint コマンドが削除。next build もリントを実行しなくなったので、BiomeかESLintを直接実行する
  • AMPサポートが全面削除(useAmp・amp設定)
  • serverRuntimeConfig / publicRuntimeConfig が削除。環境変数(クライアントは NEXT_PUBLIC_ プレフィックス)へ移行する
  • パラレルルートの全スロットで default.js が必須に(無いとビルド失敗。notFound() か null を返す)
  • next dev と next build の出力先が分離され(devは .next/dev)、同時実行が可能に
  • グローバルな scroll-behavior: smooth をナビゲーション時に上書きしなくなった(従来挙動には html に data-scroll-behavior="smooth" を付与)

React面では、App RouterがReact 19.2ベースになり、View Transitions・useEffectEventActivity が使えるようになりました。

React Compiler対応も安定版となり、reactCompiler: true で自動メモ化を有効にできます(Babel依存のためビルド時間は増える点に注意)。React 19の新機能自体は以下の記事で詳しく解説しています。

React 19実践|useEffectが減る新機能8選forwardRef はもういらない。フォーム処理は useActionState と useOptimistic で数行に。React 19 で正式に使えるようになった新機能を、そのまま動く8つの実践コードで一気に紹介します。useEffect が確実に減ります。frontendlab.magicgifted.com

まとめ|移行チェックリスト

  1. Node.js 20.9以上・TypeScript 5.1以上へ更新する
  2. pnpm dlx @next/codemod@canary upgrade latest を実行する
  3. package.json から --turbopack フラグを外し、カスタムwebpack設定の扱い(移行 or --webpack)を決める
  4. params・searchParams・cookies() 等に await が付いているか確認する(npx next typegen で型ヘルパー生成)
  5. middleware.ts を proxy.ts へリネームする(edgeランタイム利用時は据え置き)
  6. revalidateTag に第2引数を追加し、即時反映が必要な箇所は updateTag へ置き換える
  7. next/image のデフォルト変更(TTL・quality・ローカル画像のクエリ)が影響しないか確認する
  8. next lint を使っていた場合はESLint CLIまたはBiomeへ移行する

破壊的変更の数は多いものの、codemodと型ヘルパーの整備によって移行体験そのものは過去のメジャーアップデートより整っています。まずは開発環境でcodemodを流し、ビルドエラーが出た箇所をこのチェックリストで潰していくのが最短ルートです。

Next.jsプロジェクトの構成を見直したい方は、実務で使っているディレクトリ設計の記事もあわせてどうぞ。

私が実務で採用しているNext.jsのディレクトリ設計を公開しますNext.js(App Router)のディレクトリ設計に正解はないものの、実務で運用して破綻しなかった構成には共通点があります。pageの4分割、API層の操作単位の分割、コンポーネントの置き場所のルールまで、現役エンジニアが実際に採用している設計を理由つきで公開します。frontendlab.magicgifted.com