tech·

Next.js 16の新機能まとめ|Turbopackデフォルト化・proxy.ts・React 19完全対応

Next.js 16の主要変更点を実務目線で解説。Turbopackがデフォルトバンドラーになったことによるビルド高速化、middleware.tsからproxy.tsへの移行、React 19完全対応、PPRの安定化、after()APIの活用まで網羅します。

Next.js 16の新機能まとめ|Turbopackデフォルト化・proxy.ts・React 19完全対応

Next.js 16は、2025年秋にリリースされた大型バージョンです。Turbopackのデフォルト化、middleware.tsからproxy.tsへのリネーム、React 19の完全サポートなど、開発体験とパフォーマンスの両面で重要な変更が加わりました。

本記事では、実際のプロジェクトに影響する変更点を優先度順に解説します。

この記事を読むとわかること

  • Turbopackデフォルト化で何が変わるか(数値付き)
  • proxy.tsへの移行が必要かどうかの判断基準
  • React 19対応で恩恵を受けるコードパターン
  • Partial Prerendering(PPR)が安定版になった意味
  • after() APIの実用的な使い方

1. Turbopackがデフォルトバンドラーに

Next.js 16最大の変更点は、Turbopackがデフォルトのバンドラーになったことです。Next.js 15では--turbopackフラグを明示的に指定する必要がありましたが、16からはフラグなしで自動的にTurbopackが使われます。

# Next.js 15まで(Turbopackを使うには明示的に指定)
next dev --turbopack

# Next.js 16(フラグ不要)
next dev

ビルド速度の改善幅

Vercelの公式ベンチマークでは、大規模プロジェクト(1,000コンポーネント以上)において以下の改善が報告されています。

指標webpackTurbopack
初回コールドスタート〜30秒〜8秒
HMR(ファイル保存後の反映)〜2秒〜200ms
本番ビルド〜3分〜90秒

HMRの高速化は体感として最もわかりやすく、スタイル変更やコンポーネント修正がほぼ即座にブラウザに反映されるようになります。

webpack設定の移行

Turbopackはwebpackのプラグインシステムと互換性がないため、next.config.jsでwebpack固有の設定をしている場合は確認が必要です。

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // webpack設定がある場合はTurbopack用の設定に書き換えが必要
  turbopack: {
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
    },
  },
};

多くのプロジェクトではwebpack設定を使っていないため、設定ファイルを変更せずにそのまま動作します。next devを実行してエラーが出なければ追加対応は不要です。

2. middleware.tsproxy.ts へのリネーム

Next.js 16では、middleware.tsproxy.tsにリネームされました。機能は完全に同一ですが、ファイル名が「プロキシとして動作する」という役割をより正確に表現するものに変更されています。

移行方法

# ファイル名を変更するだけ
mv middleware.ts proxy.ts
mv middleware.js proxy.js

エクスポートするオブジェクト名も変更されています。

// Before(middleware.ts)
export function middleware(request: NextRequest) {
  // ...
}
export const config = {
  matcher: ['/api/:path*'],
};

// After(proxy.ts)
export function proxy(request: NextRequest) {
  // ...
}
export const config = {
  matcher: ['/api/:path*'],
};

middleware.tsは後方互換として当面サポートされますが、Next.js 17で廃止予定のため、新規プロジェクトではproxy.tsを使うことが推奨されています。

既存プロジェクトの対応タイミング

  • 新規プロジェクト ── 最初からproxy.tsを使う
  • 既存プロジェクト ── 次の機能開発タイミングで移行(緊急性は低い)
  • マイクロフロントエンド ── 本番デプロイ前に確認推奨

3. React 19 完全サポート

Next.js 16はReact 19を完全にサポートします。特に実用的な変更点を3つ紹介します。

Server Actionsの改善

React 19ではuseActionState(旧useFormState)が安定版になりました。フォーム送信のパターンが整理され、より直感的に書けます。

// app/actions.ts
'use server';

export async function submitForm(prevState: unknown, formData: FormData) {
  const name = formData.get('name') as string;

  if (!name) {
    return { error: '名前を入力してください' };
  }

  await saveToDatabase(name);
  return { success: true };
}

// app/form.tsx
'use client';

import { useActionState } from 'react';
import { submitForm } from './actions';

export function Form() {
  const [state, formAction, isPending] = useActionState(submitForm, null);

  return (
    <form action={formAction}>
      <input name="name" />
      {state?.error && <p className="text-red-500">{state.error}</p>}
      <button type="submit" disabled={isPending}>
        {isPending ? '送信中...' : '送信'}
      </button>
    </form>
  );
}

use() フックの活用

React 19で安定化したuse()フックを使うと、Promiseをコンポーネント内で直接処理できます。

import { use, Suspense } from 'react';

async function fetchUser(id: string) {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
}

function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
  const user = use(userPromise); // Promiseを直接渡す
  return <div>{user.name}</div>;
}

export default function Page({ params }: { params: { id: string } }) {
  const userPromise = fetchUser(params.id);

  return (
    <Suspense fallback={<div>読み込み中...</div>}>
      <UserProfile userPromise={userPromise} />
    </Suspense>
  );
}

Context の簡略化

React 19からContext.Providerの代わりにContextを直接JSXとして使えます。

// Before
<ThemeContext.Provider value={theme}>
  <App />
</ThemeContext.Provider>

// After(React 19)
<ThemeContext value={theme}>
  <App />
</ThemeContext>

4. Partial Prerendering(PPR)の安定化

Next.js 14から実験的機能として提供されていた**Partial Prerendering(PPR)**が、Next.js 16で安定版になりました。

PPRとは何か

PPRは、同一のページ内でStaticな部分とDynamicな部分を混在させるレンダリング方式です。

┌─────────────────────────────────────┐
│  ヘッダー(Static)← 即座に表示     │
├─────────────────────────────────────┤
│  商品一覧(Static)← 即座に表示     │
├─────────────────────────────────────┤
│  [カート数] (Dynamic)← ストリーミング│
└─────────────────────────────────────┘

従来のNext.jsでは、ページ内に1つでもDynamicな部分があると、ページ全体がSSR(サーバーレンダリング)になりました。PPRではStaticな部分が先に配信され、Dynamicな部分は後からストリーミングされます。

有効化と使い方

// next.config.js
const nextConfig = {
  experimental: {
    ppr: true, // Next.js 16では stable に移行
  },
};
// app/products/page.tsx
import { Suspense } from 'react';

export default function ProductsPage() {
  return (
    <>
      <h1>商品一覧</h1>
      <StaticProductList />  {/* Staticとして扱われる */}
      <Suspense fallback={<CartSkeleton />}>
        <DynamicCart />       {/* Dynamicとしてストリーミング */}
      </Suspense>
    </>
  );
}

ECサイトや情報サイトのように「基本情報は静的、ユーザー固有情報は動的」というパターンで大きな恩恵を受けます。

5. after() API の正式サポート

Next.js 15.1で導入されたafter()APIがNext.js 16で安定版になりました。これは、レスポンスを返した後に処理を行うための仕組みです。

典型的なユースケース

// app/api/purchase/route.ts
import { after } from 'next/server';

export async function POST(request: Request) {
  const { productId, userId } = await request.json();

  // 購入処理(レスポンス前に完了させる必要がある処理)
  const order = await createOrder(productId, userId);

  // レスポンスを返す
  const response = Response.json({ orderId: order.id });

  // after()内の処理はレスポンス送信後に実行される
  after(async () => {
    await sendOrderConfirmationEmail(userId, order.id);
    await updateInventory(productId);
    await logPurchaseEvent(userId, productId);
  });

  return response;
}

after()を使うことで、ユーザーへのレスポンスを遅らせることなく、ログ記録・メール送信・在庫更新などの後処理を行えます。

6. キャッシュ制御の改善

Next.js 16ではcacheTag()cacheLife()が安定版になり、より細かいキャッシュ制御が可能になりました。

// app/products/[id]/page.tsx
import { unstable_cacheTag as cacheTag, unstable_cacheLife as cacheLife } from 'next/cache';

async function getProduct(id: string) {
  'use cache';
  cacheTag(`product-${id}`);
  cacheLife('hours'); // 1時間キャッシュ

  const res = await fetch(`https://api.example.com/products/${id}`);
  return res.json();
}
// app/api/products/[id]/route.ts
import { revalidateTag } from 'next/cache';

// 商品情報が更新されたときに特定のキャッシュだけ無効化
export async function PUT(request: Request, { params }: { params: { id: string } }) {
  await updateProduct(params.id, await request.json());
  revalidateTag(`product-${params.id}`); // このタグのキャッシュのみ再検証
  return Response.json({ success: true });
}

Next.js 16 へのアップグレード手順

# パッケージのアップグレード
npm install next@16 react@19 react-dom@19

# TypeScriptを使っている場合
npm install --save-dev @types/react@19 @types/react-dom@19

アップグレード後の確認チェックリスト

  • next dev が起動するか確認(Turbopackエラーの有無)
  • middleware.ts がある場合は動作確認(proxy.tsへの移行は任意)
  • useFormState を使っている場合は useActionState への移行検討
  • Context.Provider の記法は引き続き動作するが、新記法への移行も検討
  • 本番ビルド(next build)のエラーなし確認

まとめ

Next.js 16の変更をひと言でまとめると、**「実験的機能の卒業と開発体験の洗練」**です。

Turbopackのデフォルト化により開発中のHMRが劇的に速くなり、PPRやafter()の安定化により本番環境でのパフォーマンス最適化の選択肢が増えました。React 19との組み合わせで、Server Actionsを使ったフォーム処理もシンプルに書けるようになっています。

破壊的変更はproxy.tsのリネームのみで、移行の緊急性は低い。既存プロジェクトもnpm install next@16でほぼそのまま動作するため、アップグレードのハードルは低いバージョンです。

koromo からの提案

AIツールの導入判断は、突き詰めると「投資対効果が合うか」「リスクを管理できるか」「事業にどう効くか」の3点に帰着します。koromo では、この判断に必要な材料を整理するところからご支援しています。

以下のような状況にある方は、まず現状の整理だけでも前に進むきっかけになります。

  • AIで開発や業務を効率化したいが、自社に合う方法がわからない
  • 社内にエンジニアがいない / 少人数で、AI導入の進め方に見当がつかない
  • 外注先の開発会社にAI活用を提案したいが、何を求めればいいか整理できていない
  • 「AIを使えばコスト削減できるはず」と感じているが、具体的な試算ができていない

ツールを使った上で相談したい方はお問い合わせフォームから「AI活用の相談」とご記載ください。初回の壁打ち(30分)は無料で対応しています。

関連記事