Turbopackとは?Next.js 16で既定になったRust製バンドラの設定と移行判断
Turbopackは、JavaScriptとTypeScriptを対象にVercelが開発したRust製のインクリメンタルバンドラで、Next.jsに内蔵されています。npm registryで2026年8月1日に確認したnextのlatestは16.2.12で、この系列ではコマンドに何も付けなければTurbopackが動きます。単体で入れるパッケージではなく、Next.jsのビルド基盤そのものが差し替わったと捉えると位置づけを誤りません。この記事では、Turbopackが速さを出している4つの設計、devとbuildそれぞれの起動と--webpackでの戻し方、next.config.jsに書ける設定キー、ファイルシステムキャッシュの現在地、webpackから移した際に踏む非互換、そして受託開発で採用してよい条件までを実装目線で扱います。
まとめ:Turbopackを採用してよい条件とwebpackを残す判断
結論を先に示します。Next.js 16系で新規に組む案件なら、Turbopackを既定のまま使って構いません。dev向けは15.0.0で安定版に到達し、buildも15.5.0のベータを経て16.0.0で既定になっており、意図的に外す理由がない限り追加の設定は不要です。CSS Modules、Sass、PostCSS、React Server Components、Fast Refreshはいずれも設定なしで動きます。
webpackを残す判断が要るのは3つの場合に絞られます。第一にwebpackプラグインへ依存している構成。Turbopackはプラグイン機構を持たずローダーだけを引き継ぐため、プラグイン前提のツール連携は動きません。第二にYarn PnP、esmExternals、urlImportsといった実装予定のない機能を使っている構成。第三にsassOptions.functionsでJavaScript関数をSassから呼んでいる構成です。この3つに当たらないなら--webpackを外して進められます。
Turbopackの定義|Rust製インクリメンタルバンドラの設計思想
最初に、Turbopackが何をするものなのかを設計の狙いから押さえます。ここを飛ばすと、後段の設定キーや非互換が単なる暗記事項になってしまいます。
統一グラフと関数単位キャッシュと遅延バンドルが速さを生む理屈
公式ドキュメントは、Turbopackを作った狙いとして4点を挙げています。1つ目が統一グラフで、クライアント向けとサーバー向けという複数の出力環境をひとつのグラフで扱い、コンパイラを並べて結果を継ぎ合わせる手間をなくす設計です。2つ目がバンドルの方針。開発時にバンドルせずブラウザのネイティブESMへ委ねる手法は小規模なら快適でも、大規模アプリではリクエスト数が膨らんで遅くなります。Turbopackは開発時もバンドルする側に立ちました。
3つ目がインクリメンタル計算です。処理をコア間で並列に流し、結果を関数単位でキャッシュするため、一度終えた計算は繰り返しません。4つ目が遅延バンドルで、開発サーバーへ実際に要求されたものだけを組み立てます。画面数の多い業務アプリほど差が出る設計です。バンドラー一般の仕組みから整理したい場合は、Rollupで学ぶJavaScriptバンドラーの基礎が土台になります。
dev安定版から既定バンドラへ進んだバージョン履歴の読み解き方
成熟度は公式のバージョン履歴で確認できます。15.0.0でnext dev向けが安定版になり、15.3.0でnext buildへの対応が実験段階として入りました。15.5.0でビルド対応がベータへ、そして16.0.0でTurbopackがNext.jsの既定バンドラになっています。同じ16.0.0では、Babelの設定ファイルを検出したときにBabelを自動で組み込む挙動も入りました。
| 版 | Turbopackの状態 |
|---|---|
| 15.0.0 | dev向けが安定版 |
| 15.3.0 | build対応が実験段階 |
| 15.5.0 | build対応がベータ |
| 16.0.0 | 既定バンドラ・Babel自動対応 |
| 16.2.12 | 2026年8月1日のlatest |
devとbuildで成熟度がずれてきた歴史を押さえておくと判断がぶれません。dev側は2年近く安定版として使われてきた一方、build側が既定になったのは16.0.0からです。16系へ上げた案件でビルド周りの挙動が変わったなら、まずここを疑ってください。16系全体の変更点はNext.js 16の主要機能をまとめた解説で確認できます。
ネイティブバインディングの配布形態と動作するプラットフォーム
Rust実装であるため、Turbopackはプラットフォーム別のネイティブバインディングを必要とします。npmでnext 16.2.12のメタデータを見ると、@next/swc-darwin-arm64、@next/swc-linux-x64-musl、@next/swc-win32-x64-msvcなど8つのパッケージがoptionalDependenciesに並び、インストール時は環境へ合うものだけが降りてきました。Turbopackのネイティブコードもここに含まれます。
公式が対応を明記しているのはmacOS、Windows、Linux(glibc)、Linux(musl)の4種で、いずれもx64とARM64です。FreeBSDやOpenBSDのようにネイティブバインディングがない環境では、Next.jsがWASMバインディングへ退避します。WASM側はSWCのコンパイルと圧縮には対応するものの、Turbopackには対応しません。この環境ではnext dev --webpackのようにフラグの明示が要ります。
next devとnext buildでの起動方法とwebpackへの戻し方
次に、実際のコマンドと設定ファイルの書き方を確認します。16系では書くことがほとんど残っていないのが実情です。
設定不要で有効になる既定動作とpackage.jsonの書き方
Turbopackが既定になったため、package.jsonのscriptsは素のコマンドのままで構いません。15系で必要だった--turbopackフラグはもう付けなくても動きます。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
この状態でJavaScriptとTypeScriptはSWCが処理し、JSXとTSXもSWC経由でコンパイルされます。注意したいのは型検査で、Turbopackは型チェックを行いません。tsc --watchを別プロセスで走らせるか、エディタ側の型検査に任せる運用が前提です。CIで型エラーを止めたいなら、ビルドとは別に型チェックのステップを置いてください。
webpackへ戻すオプトアウトの手順と切り替えを残す運用設計
webpackへ戻すのはフラグ1つです。devとbuildそれぞれに--webpackを付けます。
{
"scripts": {
"dev": "next dev --webpack",
"build": "next build --webpack",
"start": "next start"
}
}
移行期は、既定のscriptsをTurbopackのままにし、dev:webpackとbuild:webpackを別名で残す形が扱いやすい構成です。挙動の違いを疑ったとき、同じリポジトリで両方を走らせて切り分けられます。ただし長く維持するとwebpack側の設定だけが古びるため、切り替え用のscriptsは移行完了後に削除する前提で置いてください。
next.config.jsのturbopackキーで書く4つの設定項目
Turbopackの設定は、next.config.js(またはnext.config.ts)のturbopackキーの下に書きます。webpack時代のwebpack()関数は認識されないため、そこに書いていた内容は移し替えが要ります。
module.exports = {
turbopack: {
resolveAlias: {
underscore: 'lodash',
},
resolveExtensions: ['.mdx', '.tsx', '.ts', '.jsx', '.js', '.json'],
},
}
| キー | 役割 |
|---|---|
| rules | webpackローダーの追加指定 |
| resolveAlias | 手動エイリアスの定義 |
| resolveExtensions | 解決対象の拡張子を変更 |
| ignoreIssue | 特定の警告表示を抑止 |
| root | ファイルシステムルート指定 |
パスエイリアスは設定が不要な場面が多くあります。tsconfig.jsonのpathsとbaseUrlをTurbopackが読むためで、Next.jsの従来挙動と揃っています。
Turbopackのファイルシステムキャッシュ有効化とビルド時間の測り方
webpackにはディスクへビルド結果を保存するキャッシュがあります。Turbopackにも相当する機能が用意されていますが、状態がdevとbuildで分かれている点に注意が要ります。
開発サーバーでは既定で有効・ビルドではオプトインという現在地
Next.js 16以降、Turbopackのファイルシステムキャッシュは実験フラグで制御します。experimental.turbopackFileSystemCacheForDevは既定で有効、experimental.turbopackFileSystemCacheForBuildは現時点でオプトインです。公式はこの機能をベータと位置づけています。ビルド側で恩恵を得たいなら明示的に有効化してください。実際の効き方と設定例は、Next.js 16.3の永続キャッシュとメモリ削減の実装解説に数値付きでまとめてあります。
速度を比較するときwebpackと条件を揃える2つの下ごしらえ
キャッシュの存在は計測を歪めます。公式も注意を促しており、比較の前に条件を揃えるのが筋です。1つ目は、ビルドのたびに.nextフォルダを削除してコールドビルド同士を比べること。2つ目は、両者ともキャッシュを有効にしてウォームビルド同士を比べることです。片方だけキャッシュが効いた数字は判断材料になりません。
この計測を見積もりの根拠にするなら、コールドとウォームの両方を最低3回ずつ取り、中央値で比べる手順を決めておくと案件間で数字を並べられます。
本番ビルドと開発で既定値が変わる実験フラグの一覧とその読み方
experimental配下には、Turbopackの挙動を細かく変えるフラグが並ぶ構成です。多くはdevとbuildで既定値が異なるため、開発中は問題なくビルドで挙動が変わる、という現象の説明が付きます。以下はいずれもturbopackで始まる名前で、表では接頭辞を省いています。
| フラグ名(turbopack省略) | dev既定 | build既定 |
|---|---|---|
| Minify | false | true |
| TreeShaking | false | false |
| ScopeHoisting | false | true |
| RemoveUnusedImports | false | true |
| ModuleIds | named | deterministic |
| SourceMaps | true | 設定値に追従 |
読み方の勘所は3つです。圧縮とスコープホイスティングは本番でのみ有効なので、本番だけで壊れる不具合はこの2つを疑う順番になります。モジュールIDはdevがnamed、buildがdeterministicのため、IDに依存したコードは本番で破綻します。ソースマップはdevで有効、buildではproductionBrowserSourceMapsの設定に従うので、本番のスタックトレースが読めない場合はここを見てください。
webpackとの非互換5点|移行作業で踏みやすい落とし穴と回避策
ここからが移行の本題です。公式が「非自明な挙動差」として挙げている項目のうち、実務で当たりやすいものを5つ取り上げます。新規アプリではほぼ問題にならず、既存アプリの移行で効いてくる部分です。
webpackプラグインは非対応でローダーだけが引き継がれる
Turbopackはwebpackのプラグイン機構を持ちません。プラグインでビルドへ割り込む前提のサードパーティ製ツールは、そのままでは連携できないと考えてください。一方でwebpackローダーには対応しており、turbopack.rulesで指定できます。移行時はまず既存のwebpack設定をプラグイン欄とローダー欄へ仕分けると作業量が読め、代替の見つからないプラグインがあればその構成だけwebpackを残す判断へ進めます。
ファイルシステムルートの外に置いたnpm linkが解決されない
Turbopackはルートディレクトリを基準にモジュールを解決し、プロジェクトルートの外にあるファイルは既定で解決対象に入りません。npm link、yarn link、pnpm linkでリポジトリ外の依存を参照している構成では、リンク先が見つからない事象が起きます。回避策はturbopack.rootで、プロジェクトとリンク先の両方を含む親ディレクトリを指すことです。モノレポの相互参照も同じ考え方で対処できます。
CSSモジュールの読み込み順とレガシー記法の非対応で崩れる箇所
Turbopackは、順序が明示されていないCSS Modulesの並びをJSのimport順に従って決めます。webpackも概ね同様に振る舞いますが、副作用のないファイルと推論した場合などにJS由来の順序を無視するケースがあり、そこに依存していた見た目が移行後に変わります。対処はどちらかです。片方のモジュールからもう片方を@importして順序を固定するか、同じプロパティを奪い合っているルールを特定して衝突自体をなくすか。
加えて、レガシー扱いのCSS Modules機能が落ちました。単独の:localと:global擬似クラス(関数形式の:global(...)のみ対応)、@valueルール、ICSSの:importと:exportが該当します。composesや@importで通常の.cssを参照している箇所も、Turbopackでは常にグローバルCSS扱いになるため、参照先を.module.cssへ改名する対応が要ります。
Sassのチルダ記法とsassOptions.functionsの扱い
Sassは2点あります。1点目はnode_modules内のSassを読む書き方で、webpackのチルダ記法は引き継がれていません。指定を書き換えるのが本筋です。
@import 'bootstrap/dist/css/bootstrap.min.css';
import文へ手を入れられないなら、turbopack.resolveAliasでチルダをパスへ写す逃げ道もあります。2点目はsassOptions.functionsです。Sassのコードから呼ばれるJavaScript関数を定義する機能で、Node.js上で完結するsass-loaderだから成り立っていました。Rust実装のTurbopackはJavaScript関数を直接実行できないため、この機能を使う構成はwebpackを選ぶ判断になります。
Yarn PnPやesmExternalsなど実装予定のない非対応機能
公式が「実装予定なし」と明記している項目もあります。Yarn PnP、experimental.urlImports、experimental.esmExternalsの3つです。一方、experimental.nextScriptWorkersとexperimental.fallbackNodePolyfillsは将来対応とされており、待つ余地が残ります。またApp Routerでルートレイアウトを自動生成する挙動は非対応で、手動作成を促すメッセージが出ます。
受託開発でTurbopackを採用してよい条件と見送るべき場面
仕様の確認を踏まえて、案件でどう扱うかを言い切ります。ここは公式ドキュメントに書かれていない、現場側の判断です。
新規案件でTurbopackを既定のまま使ってよい3つの前提条件
新規のNext.js 16系案件は、次の3条件を満たすなら既定のまま進めて構いません。第一に、ビルド環境がmacOS・Windows・Linuxのx64かARM64であること。CIランナーとローカルの両方を確認します。第二に、webpackプラグインを前提とする社内ツールやサードパーティ連携を持ち込まないこと。第三に、Sassのカスタム関数とYarn PnPを使わないこと。この3つが揃えば、追加の設定を書かずに開発と本番ビルドの双方をTurbopackへ載せられます。
フレームワークごと比べている段階ならNext.jsとNuxtの違いを整理した比較を、Rust製ビルドツールという括りで他の選択肢も見るならFarm(farm-fe)とViteやRspackとの違いが対比の材料です。Go製で速度に振り切った選択肢まで並べるならesbuildの使い方と採用判断も比較の対象に入ります。
webpackを残す判断が要る既存プロジェクトの3つの見分け方
既存プロジェクトを16系へ上げるときは、移行前に3つを機械的に洗い出してください。1つ目、next.config.jsにwebpack()関数があるか。あるなら中身をプラグインとローダーへ仕分けます。2つ目、package.jsonのpackageManagerとyarnrcを見てYarn PnPを使っていないか。3つ目、.scssファイルにチルダ記法が残っていないか、sassOptions.functionsの定義がないか。
この3点すべてが空振りなら、--webpackを外して様子を見る段階へ進めます。1つでも当たったなら、その項目の代替を決めるまでwebpackを維持するのが安全側の判断です。先送りしたまま16系へ上げると、ビルドは通るのに本番だけ見た目が崩れる、という切り分けの難しい状態に陥ります。
段階的に移行する手順と受託開発の見積もりに織り込むべき検証工数
移行の順路は3段階です。まずdevだけをTurbopackにして日常の開発で1週間ほど回し、Fast Refreshとスタイルの挙動を見ます。次にステージング環境のビルドを切り替え、CSSの読み込み順と本番専用フラグの影響を目視で検証します。最後に本番ビルドを切り替え、--webpackのscriptsを1リリース分だけ残してから削除する流れです。Vite系から移ってきた構成なら@vitejs/plugin-reactの設定と役割との対比で差分が掴めます。
見積もりに織り込むべきなのは、切り替え作業そのものより検証の工数です。CSS Modulesの順序差は自動テストで拾いにくく、主要画面の目視確認とスクリーンショット比較が現実的な手段になります。画面数の多い業務システムでは、この検証だけで数人日を見ておくのが妥当な線です。既存のNext.jsアプリを16系へ引き上げる作業やバンドラ移行を含む改修は業務用・Webアプリ開発で対応しています。
Turbopackの導入と移行について実装者から届く質問への回答
Turbopackを使うのに別途インストールは必要ですか?
不要です。Next.jsに内蔵されており、nextパッケージを入れた時点でプラットフォーム別のネイティブバインディングも一緒に降りてきます。16系ではコマンドへ何も付けなければ動くため、package.jsonの書き換えも要りません。15系から上げるなら、逆に--turbopackフラグを外して構わない状態です。
Turbopackはwebpackよりどのくらい速くなりますか?
公称値をそのまま自社案件へ当てはめないでください。差は依存の数、画面数、CSSの構成で変わります。.nextを削除したコールドビルド同士か、双方キャッシュを有効にしたウォームビルド同士で、条件を揃えて手元で測るのが唯一の方法です。
本番ビルドでTurbopackを使っても問題ないでしょうか?
Next.js 16.0.0でTurbopackが既定バンドラになったため、公式が本番ビルドを想定した状態です。ただしファイルシステムキャッシュのビルド向けはベータかつオプトインで、ここだけは成熟度が一段違います。本番のビルド時間短縮を狙って有効化する場合は、キャッシュを消したビルドでも同じ成果物が出ることを一度確認しておくと安心して運用に乗せられます。
Babelの設定ファイルがあるプロジェクトでも動きますか?
Next.js 16以降、Babelの設定ファイルを検出すると自動でBabelが組み込まれます。ただしNext.js内部の変換と古いECMAScriptへのダウンレベルは常にSWCが担当します。webpackではBabel設定があるとSWCが無効になっていたので、この点は挙動差として覚えておいてください。node_modules配下はBabelの対象外で、必要ならbabel-loaderを手動で設定します。
Turbopackで遅い・落ちるときは何を送ればよいですか?
トレースファイルを作って添えるのが最短です。dev起動時にNEXT_TURBOPACK_TRACING=1を付けて実行すると、.nextディレクトリの下にトレースが出力されます。これをNext.jsのリポジトリへIssueを起票する際に添付してください。手元での切り分けは、同じ操作が--webpackでも再現するか試すと早く進みます。
関連記事
- Next.js 16とは?ReactベースのWeb開発フレームワーク最新版の概要や主要機能を詳しく紹介:16系全体の変更点を確認できます
- Next.js 16.3とは?Turbopack永続キャッシュとInstant Navigationsなど新機能を実装者目線で解説:永続キャッシュの設定例と実測値が載っています
- Rollupとは|JavaScriptバンドラーのnpm導入から使い方・Webpack/Viteとの違いまで:バンドラーの基本動作を押さえられます
- Rust製ビルドツールFarm(farm-fe)とは?Vite・Rspackとの違いと使い方:Rust製ツール同士の比較材料です
- Nuxtとは?Vue製フレームワークの構成と採用判断を実装目線で解説:Next.js以外の選択肢の検討に役立ちます
- SWCとは?Rust製コンパイラの設定と採用判断を実装目線で解説:Turbopackが内部で使う変換器を掘り下げています
- esbuildとは?Go製の高速バンドラの使い方と採用判断を実装目線で解説:Go製バンドラとの比較材料です