---
title: "Turbopackとは：Next.js 16で既定になったRust製バンドラの設定と移行判断"
url: "https://www.issoh.co.jp/tech/details/16015/"
published: 2026-08-01
updated: 2026-09-16
categories: ["開発"]
publisher: "株式会社一創"
---

# Turbopackとは：Next.js 16で既定になったRust製バンドラの設定と移行判断

Turbopackは、JavaScriptとTypeScriptを対象にVercelが開発したRust製のインクリメンタルバンドラで、Next.jsに内蔵されています。npmレジストリで2026年9月16日に確認したnextのlatestは16.3.5で、この系列ではコマンドに何も付けなければTurbopackが動きます。単体で入れるパッケージではなく、Next.jsのビルド基盤そのものが差し替わったと捉えると位置づけを誤りません。この記事では、Turbopackが速さを出している4つの設計、devとbuildそれぞれの起動と`--webpack`での戻し方、next.config.jsに書ける設定キー、Turbopackでしか動かない`import.meta.env`と`import.meta.glob`、ファイルシステムキャッシュの現在地、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はいずれも設定なしで動きます。ファイルシステムキャッシュもdevとbuildの双方で既定が有効に変わり、16.3系では自分で有効化する作業も消えました。

webpackを残す判断が要るのは3つの場合に絞られます。第一にwebpackプラグインへ依存している構成。Turbopackはプラグイン機構を持たずローダーだけを引き継ぐため、プラグイン前提のツール連携は動きません。第二にYarn PnP、esmExternals、urlImportsといった実装予定のない機能を使っている構成。第三にsassOptions.functionsでJavaScript関数をSassから呼んでいる構成です。この3つに当たらないなら`--webpack`を外して進められます。Next.jsそのものの構成から確認したい場合は[Next.jsの最小アプリを動かす手順と採用判断](https://www.issoh.co.jp/tech/details/17373/)を先に読むと、この記事の設定項目がどこに効くのか掴めます。

## Turbopackの定義｜Rust製インクリメンタルバンドラの設計思想

最初に、Turbopackが何をするものなのかを設計の狙いから押さえます。ここを飛ばすと、後段の設定キーや非互換が単なる暗記事項になってしまいます。

### 統一グラフと関数単位キャッシュと遅延バンドルが速さを生む理屈

[Next.js公式のTurbopackドキュメント](https://nextjs.org/docs/app/api-reference/turbopack)は、Turbopackを作った狙いとして4点を挙げています。1つ目が統一グラフで、クライアント向けとサーバー向けという複数の出力環境をひとつのグラフで扱い、コンパイラを並べて結果を継ぎ合わせる手間をなくす設計です。2つ目がバンドルの方針。開発時にバンドルせずブラウザのネイティブESMへ委ねる手法は小規模なら快適でも、大規模アプリではリクエスト数が膨らんで遅くなります。Turbopackは開発時もバンドルする側に立ちました。

3つ目がインクリメンタル計算です。処理をコア間で並列に流し、結果を関数単位でキャッシュするため、一度終えた計算は繰り返しません。この結果は実行の合間にディスクへも残ります。4つ目が遅延バンドルで、開発サーバーへ実際に要求されたものだけを組み立てます。画面数の多い業務アプリほど差が出る設計です。バンドラー一般の仕組みから整理したい場合は、[Rollupで学ぶJavaScriptバンドラーの基礎](https://www.issoh.co.jp/tech/details/7525/)が土台になります。

### 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.3.5 | 2026年9月16日のlatest |

devとbuildで成熟度がずれてきた歴史を押さえておくと判断がぶれません。dev側は2年近く安定版として使われてきた一方、build側が既定になったのは16.0.0からです。16系へ上げた案件でビルド周りの挙動が変わったなら、まずここを疑ってください。16系全体の変更点は[Next.js 16の主要機能をまとめた解説](https://www.issoh.co.jp/tech/details/9596/)で確認できます。

### ネイティブバインディングの配布形態と動作するプラットフォーム

Rust実装であるため、Turbopackはプラットフォーム別のネイティブバインディングを必要とします。[npmレジストリのnextメタデータ](https://registry.npmjs.org/next/latest)を2026年9月16日に見ると、@next/swc-darwin-arm64、@next/swc-linux-x64-musl、@next/swc-win32-arm64-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](https://www.issoh.co.jp/tech/details/16019/)が処理し、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()`関数は認識されないため、そこに書いていた内容は移し替えが必要です。各キーの詳細な引数は[turbopack設定のAPIリファレンス](https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack)に一覧があります。

```
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の従来挙動と揃っています。

## import.meta.envとglobをTurbopackで書く実装手順

ここからは、webpackでは動かずTurbopackでだけ動くAPIを扱います。移行の副産物として手に入る機能で、環境判定のコードとディレクトリ一括読み込みの書き方が短くなります。Viteを触ったことがあるなら見覚えのある形です。Vite側の設計と比べたい場合は[Viteの環境構築手順と8系の変更点](https://www.issoh.co.jp/tech/details/3587/)が対応表の代わりになります。

### import.meta.envの5つのプロパティで分岐を静的に削る書き方

Turbopackに組み込まれている環境メタデータが`import.meta.env`です。用意されているのは5つで、`DEV`と`PROD`と`MODE`がコンパイル時のNODE\_ENVに、`BASE_URL`がNext.jsのbasePath（末尾スラッシュ付き）に、`SSR`がサーバー側バンドルかどうかに対応します。値は静的に解析されるため、到達しない分岐はビルド結果から消えます。

```
if (import.meta.env.DEV) {
  console.log('development mode')
}

const { MODE, SSR } = import.meta.env
const baseUrl = import.meta.env['BASE_URL']
```

| プロパティ     | 型       | 値                 |
| --------- | ------- | ----------------- |
| DEV       | boolean | MODEがproduction以外 |
| PROD      | boolean | MODEがproduction   |
| MODE      | string  | コンパイル時のNODE\_ENV  |
| BASE\_URL | string  | basePathと末尾スラッシュ  |
| SSR       | boolean | サーバー側バンドルでtrue    |

ここで踏みやすい勘違いが2つあります。1つは`VITE_`で始まる独自変数、envPrefix、envDir、Viteのカスタムモードが使えない点。もう1つはwebpackへ戻した瞬間に`import.meta.env`ごと動かなくなる点です。`--webpack`での切り戻しを運用に残すなら、この書き方はまだ採らないという判断になります。

### import.meta.globで複数モジュールを一括読み込みする実装

`import.meta.glob()`は、globパターンに当たるファイルをまとめて取り込むVite互換のAPIです。戻り値は呼び出し元からの相対パスをキーにしたオブジェクトで、既定では各値がモジュールのPromiseを返す関数になります。遅延読み込みが既定という設計です。

```
const modules = import.meta.glob('./dir/*.js')

for (const path in modules) {
  const module = await modules[path]()
  console.log(path, module)
}

const eagerModules = import.meta.glob('./dir/*.js', { eager: true })
const rawFiles = import.meta.glob('./dir/*.txt', { query: '?raw' })
const withoutTests = import.meta.glob(['./src/**/*.js', '!**/*.test.js'])
```

| オプション         | 既定        | 役割            |
| ------------- | --------- | ------------- |
| eager         | false     | 同期で読み込む       |
| import        | undefined | 特定の名前付きexport |
| query         | undefined | クエリ文字列を付与     |
| base          | undefined | 解決の基準パス変更     |
| caseSensitive | true      | 大文字小文字の区別     |

型はNext.js側に同梱されており、tsconfig.jsonの`moduleResolution`がbundlerかnode16系なら自動で効きます。Vite 5で非推奨になった`as`オプションと`import.meta.globEager()`は引き継がれていないので、移植するコードがあるなら`query: '?raw'`と`eager: true`へ書き換えてください。記事ページやMDXをディレクトリごと束ねる処理で、手書きのimport列がまるごと消えます。

### webpack互換のマジックコメントで動的importを制御する指定

動的な`import()`、`require()`、`require.resolve()`、`new Worker()`には、バンドルの扱いを変えるマジックコメントを書けます。静的なimport文では効きません。webpack由来の`webpackIgnore`は互換があり、`turbopackIgnore`と`turbopackOptional`はTurbopack固有です。`webpackOptional`だけは双方とも非対応なので、移行時に残っていれば書き換えの対象になります。

| コメント                    | webpack | Turbopack |
| ----------------------- | ------- | --------- |
| webpackIgnore: true     | 対応      | 対応        |
| turbopackIgnore: true   | 非対応     | 対応        |
| turbopackOptional: true | 非対応     | 対応        |
| webpackOptional: true   | 非対応     | 非対応       |

実務で効くのは`turbopackOptional`です。存在しないかもしれない依存を参照する箇所で解決エラーを黙らせられるため、プラグインを差し替え可能にしている社内ライブラリの移植で使えます。ただし黙らせた先で実行時に落ちる構造は変わらないので、フォールバックの実装とセットで入れてください。

## Turbopackのファイルシステムキャッシュ有効化とビルド時間の測り方

webpackにはディスクへビルド結果を保存するキャッシュがあります。Turbopackにも相当する機能が用意されており、16.3系では既定値の扱いが変わりました。ここは過去記事や社内メモの内容が古くなりやすい箇所です。

### 開発サーバーとビルドの双方で既定有効になったキャッシュの現在地

Turbopackのファイルシステムキャッシュは実験フラグで制御します。[turbopackFileSystemCacheのリファレンス](https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopackFileSystemCache)で確認すると、`experimental.turbopackFileSystemCacheForDev`がdev既定で有効、`experimental.turbopackFileSystemCacheForBuild`もbuild既定で有効です。かつてビルド側はオプトインでしたが、その前提はもう成り立ちません。

代わりに気を付けるのは切る側の判断です。公式の注記は、ビルド環境が`.next/cache`ディレクトリを実行間で保持しない場合にfalseを指定するよう促しています。コンテナを毎回作り直すCIや、キャッシュ復元を設定していないランナーが該当します。キャッシュが残らない環境で有効のままにすると、書き出しの手間だけが乗る形になるためです。永続キャッシュの効き方と設定例は、[Next.js 16.3の永続キャッシュとメモリ削減の実装解説](https://www.issoh.co.jp/tech/details/15608/)に数値付きでまとめてあります。

### 速度を比較するときwebpackと条件を揃える2つの下ごしらえ

キャッシュの存在は計測を歪めます。公式も注意を促しており、比較の前に条件を揃えるのが筋です。1つ目は、ビルドのたびに.nextフォルダを削除してコールドビルド同士を比べること。2つ目は、両者ともキャッシュを有効にしてウォームビルド同士を比べることです。片方だけキャッシュが効いた数字は判断材料になりません。

```
rm -rf .next
time npx next build

rm -rf .next
time npx next build --webpack
```

この計測を見積もりの根拠にするなら、コールドとウォームの両方を最低3回ずつ取り、中央値で比べる手順を決めておくと案件間で数字を並べられます。パッケージマネージャを跨いで比べるときは、依存の展開方式そのものも所要時間を左右する要因です。ストアの共有まで含めた差は[pnpmの共有ストアとv12のRust実装](https://www.issoh.co.jp/tech/details/17573/)で押さえておくと、バンドラ以外の要因を切り分けられます。

### 本番ビルドと開発で既定値が変わる実験フラグの一覧とその読み方

experimental配下には、Turbopackの挙動を細かく変えるフラグが並ぶ構成です。多くはdevとbuildで既定値が異なるため、開発中は問題なくビルドで挙動が変わる、という現象の説明が付きます。以下はいずれも`turbopack`で始まる名前で、表では接頭辞を省いています。表の幅に収まらない長い名前では、クライアント側の入れ子非同期チャンク化を制御する`turbopackClientSideNestedAsyncChunking`がdevでfalse、buildでtrueという既定です。

| フラグ名（turbopack省略）      | dev既定 | build既定       |
| ---------------------- | ----- | ------------- |
| Minify                 | false | true          |
| ScopeHoisting          | false | true          |
| RemoveUnusedImports    | false | true          |
| RemoveUnusedExports    | false | true          |
| InferModuleSideEffects | true  | true          |
| ModuleIds              | named | deterministic |
| SourceMaps             | true  | 設定値に追従        |
| ModuleFragments        | false | false         |

読み方の勘所は3つです。圧縮とスコープホイスティングは本番でのみ有効なので、本番だけで壊れる不具合はこの2つを疑う順番になります。モジュールIDはdevがnamed、buildがdeterministicのため、IDに依存したコードは本番で破綻します。ソースマップはdevで有効、buildでは`productionBrowserSourceMaps`の設定に従うので、本番のスタックトレースが読めない場合はここを見てください。設定を有効にしても読めないときは、[.mapファイルの構造と生成設定](/tech/details/4330/)から切り分けます。

未使用importと未使用exportの削除は対で動く関係です。`RemoveUnusedImports`は`RemoveUnusedExports`を前提とするため、副作用を持つモジュールを暗黙のimportで読んでいた構成は本番ビルドだけ挙動が変わります。`InferModuleSideEffects`が副作用なしと推論した結果なので、疑わしいときはこのフラグをfalseにして再現するか試すのが切り分けの早道です。

## webpackとの非互換6点｜移行作業で踏みやすい落とし穴と回避策

ここからが移行の本題です。公式が「非自明な挙動差」として挙げている項目のうち、実務で当たりやすいものを6つ取り上げます。新規アプリではほぼ問題にならず、既存アプリの移行で効いてくる部分です。

### webpackプラグインは非対応でローダーだけが引き継がれる

Turbopackはwebpackのプラグイン機構を持ちません。プラグインでビルドへ割り込む前提のサードパーティ製ツールは、そのままでは連携できないと考えてください。一方でwebpackローダーには対応しており、`turbopack.rules`で指定できます。移行時はまず既存のwebpack設定をプラグイン欄とローダー欄へ仕分けると作業量が読め、代替の見つからないプラグインがあればその構成だけwebpackを残す判断へ進めます。

### ファイルシステムルートの外に置いたnpm linkが解決されない

Turbopackはルートディレクトリを基準にモジュールを解決し、プロジェクトルートの外にあるファイルは既定で解決対象に入りません。npm link、yarn link、pnpm linkでリポジトリ外の依存を参照している構成では、リンク先が見つからない事象が起きます。回避策は`turbopack.root`で、プロジェクトとリンク先の両方を含む親ディレクトリを指すことです。モノレポの相互参照も同じ考え方で対処できます。

```
const path = require('path')

module.exports = {
  turbopack: {
    root: path.join(__dirname, '..'),
  },
}
```

### 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へ改名する対応が必要です。記法そのものの前提を確認したいなら[CSS ModulesのNext.jsでの導入と型安全化](https://www.issoh.co.jp/tech/details/2917/)を先に見ておくと、どの書き方が生き残るか判断しやすくなります。

### Lightning CSSの小数5桁でline-heightの計算値がずれる箇所

TurbopackはCSSのコンパイルに[Lightning CSS](https://lightningcss.dev/)を使います。ここで効いてくるのが数値の精度差で、Lightning CSSは小数5桁、webpackは小数10桁で数値を書き出します。プレーンなCSSにもSassやSCSSの出力にも適用される差です。25を17で割った値なら、webpackが1.4705882353、Turbopackが1.47059という結果になります。

line-height、letter-spacing、calcを噛ませた幅の算定など、端数が積み上がる指定では表示差として現れます。デザイン確認をスクリーンショット比較で回している案件なら、移行直後の差分がこの精度差だけで埋まってしまう場合もあるため、注意が必要です。比較の前に、丸めた値をデザイントークン側で固定しておくと差分の読み取りが楽になります。

### Sassのチルダ記法とsassOptions.functionsの扱い

Sassは2点あります。1点目はnode\_modules内のSassを読む書き方で、webpackのチルダ記法は引き継がれていません。指定を書き換えるのが本筋です。

```
@import 'bootstrap/dist/css/bootstrap.min.css';
```

import文へ手を入れられないなら、`turbopack.resolveAlias`でチルダをパスへ写す逃げ道もあります。公式が示している書き方は次の1行で、チルダ始まりの指定を実際のパスへ流します。

```
module.exports = {
  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`は将来対応とされており、待つ余地が残ります。Lessも既定では未対応で、カスタムローダーの設定が安定した後にプラグイン経由で入る見込みです。またApp Routerでルートレイアウトを自動生成する挙動は非対応で、手動作成を促すメッセージが出ます。AMDは基本的な変換のみ通り、込み入った使い方は範囲外です。

## 受託開発でTurbopackを採用してよい条件と見送るべき場面

仕様の確認を踏まえて、案件でどう扱うかを言い切ります。ここは公式ドキュメントに書かれていない、現場側の判断です。

### 新規案件でTurbopackを既定のまま使ってよい3つの前提条件

新規のNext.js 16系案件は、次の3条件を満たすなら既定のまま進めて構いません。第一に、ビルド環境がmacOS・Windows・Linuxのx64かARM64であること。CIランナーとローカルの両方を確認します。第二に、webpackプラグインを前提とする社内ツールやサードパーティ連携を持ち込まないこと。第三に、Sassのカスタム関数とYarn PnPを使わないこと。この3つが揃えば、追加の設定を書かずに開発と本番ビルドの双方をTurbopackへ載せられます。

フレームワークごと比べている段階なら[Next.jsとNuxtの違いを整理した比較](https://www.issoh.co.jp/tech/details/2832/)を、Rust製ビルドツールという括りで他の選択肢も見るなら[Farm（farm-fe）とViteやRspackとの違い](https://www.issoh.co.jp/tech/details/3093/)が対比の材料です。Go製で速度に振り切った選択肢まで並べるなら[esbuildの使い方と採用判断](https://www.issoh.co.jp/tech/details/16017/)も比較の対象に入ります。

### webpackを残す判断が要る既存プロジェクトの3つの見分け方

既存プロジェクトを16系へ上げるときは、移行前に3つを機械的に洗い出してください。1つ目、next.config.jsに`webpack()`関数があるか。あるなら中身をプラグインとローダーへ仕分けます。2つ目、package.jsonのpackageManagerとyarnrcを見てYarn PnPを使っていないか。3つ目、.scssファイルにチルダ記法が残っていないか、sassOptions.functionsの定義がないか。

```
grep -n "webpack(" next.config.*
grep -n "pnp\|packageManager" package.json .yarnrc.yml
grep -rn "@import '~" --include=*.scss src
grep -rn "sassOptions" next.config.*
```

この4本がすべて空振りなら、`--webpack`を外して様子を見る段階へ進めます。1つでも当たったなら、その項目の代替を決めるまでwebpackを維持するのが安全側の判断です。先送りしたまま16系へ上げると、ビルドは通るのに本番だけ見た目が崩れる、という切り分けの難しい状態に陥ります。

### 段階的に移行する手順と受託開発の見積もりに織り込むべき検証工数

移行の順路は3段階です。まずdevだけをTurbopackにして日常の開発で1週間ほど回し、Fast Refreshとスタイルの挙動を見ます。次にステージング環境のビルドを切り替え、CSSの読み込み順と本番専用フラグの影響を目視で検証します。最後に本番ビルドを切り替え、`--webpack`のscriptsを1リリース分だけ残してから削除する流れです。Vite系から移ってきた構成なら[@vitejs/plugin-reactの設定と役割](https://www.issoh.co.jp/tech/details/2680/)との対比で差分が掴めます。

見積もりに織り込むべきなのは、切り替え作業そのものより検証の工数です。CSS Modulesの順序差とLightning CSSの精度差はどちらも自動テストで拾いにくく、主要画面の目視確認とスクリーンショット比較が現実的な手段になります。画面数の多い業務システムでは、この検証だけで数人日を見ておくのが妥当な線です。既存のNext.jsアプリを16系へ引き上げる作業やバンドラ移行を含む改修は[業務用・Webアプリ開発](https://www.issoh.co.jp/service/apps/business/)で対応しています。

## Turbopackの導入と移行について実装者から届く質問への回答

案件の立ち上げと移行の場面で、実装者から繰り返し届く質問を5つ集めました。turbopackという単語だけで検索した人がつまずきやすい順に並べています。

### Turbopackを使うのに別途インストールは必要ですか？

不要です。Next.jsに内蔵されており、nextパッケージを入れた時点でプラットフォーム別のネイティブバインディングも一緒に降りてきます。16系ではコマンドへ何も付けなければ動くため、package.jsonの書き換えも要りません。15系から上げるなら、逆に`--turbopack`フラグを外して構わない状態です。

### Turbopackはwebpackよりどのくらい速くなりますか？

公称値をそのまま自社案件へ当てはめないでください。差は依存の数、画面数、CSSの構成で変わります。.nextを削除したコールドビルド同士か、双方キャッシュを有効にしたウォームビルド同士で、条件を揃えて手元で測るのが唯一の方法です。16.3系ではビルドのファイルシステムキャッシュが既定で有効なので、ウォーム側は追加設定なしで再現できます。

### 本番ビルドでTurbopackを使っても問題ないでしょうか？

Next.js 16.0.0でTurbopackが既定バンドラになったため、公式が本番ビルドを想定した状態です。16.3系ではファイルシステムキャッシュもビルド既定で有効になりました。気を付けるのは、CIのように`.next/cache`が実行間で残らない環境でこの設定をfalseへ倒す判断だけです。キャッシュを消したビルドでも同じ成果物が出ることを一度確認しておくと、安心して運用に乗せられます。

### Babelの設定ファイルがあるプロジェクトでも動きますか？

Next.js 16以降、Babelの設定ファイルを検出すると自動でBabelが組み込まれます。ただしNext.js内部の変換と古いECMAScriptへのダウンレベルは常にSWCが担当します。webpackではBabel設定があるとSWCが無効になっていたので、この点は挙動差として覚えておいてください。node\_modules配下はBabelの対象外で、必要ならbabel-loaderを手動で設定します。

### Turbopackで遅い・落ちるときは何を送ればよいですか？

トレースファイルを作って添えるのが最短です。dev起動時に`--internal-trace`を付けて実行すると、`.next-profiles/trace-turbopack.bin`が出力されます。このファイルを[Next.jsのリポジトリ](https://github.com/vercel/next.js)でIssueを起票する際に添付してください。環境変数で制御していた時期の手順を紹介した情報がまだ残っているので、手元のNext.jsの版に合わせて確認するのが確実です。手元での切り分けは、同じ操作が`--webpack`でも再現するか試すと早く進みます。

```
next dev --internal-trace
```

## 関連記事

- [Next.jsとは？16系App Routerで最小アプリを動かす手順と採用判断](https://www.issoh.co.jp/tech/details/17373/)：Turbopackが動く土台を最小構成で確認できます
- [Next.js 16とは？ReactベースのWeb開発フレームワーク最新版の概要や主要機能を詳しく紹介](https://www.issoh.co.jp/tech/details/9596/)：16系全体の変更点を確認できます
- [Next.js 16.3とは？Turbopack永続キャッシュとInstant Navigationsなど新機能を実装者目線で解説](https://www.issoh.co.jp/tech/details/15608/)：永続キャッシュの設定例と実測値が載っています
- [Rollupとは｜JavaScriptバンドラーのnpm導入から使い方・Webpack/Viteとの違いまで](https://www.issoh.co.jp/tech/details/7525/)：バンドラーの基本動作を押さえられます
- [Viteとは？Reactの環境構築手順とVite 8の変更点・create-react-appからの移行](https://www.issoh.co.jp/tech/details/3587/)：import.meta系APIの元になった設計を確認できます
- [CSS Modulesとは？Next.js・TypeScriptでの導入と型安全化の設定を解説](https://www.issoh.co.jp/tech/details/2917/)：移行で影響を受けるCSS記法を押さえられます
- [Rust製ビルドツールFarm（farm-fe）とは？Vite・Rspackとの違いと使い方](https://www.issoh.co.jp/tech/details/3093/)：Rust製ツール同士の比較材料です
- [Nuxtとは？Vue製フレームワークの構成と採用判断を実装目線で解説](https://www.issoh.co.jp/tech/details/15790/)：Next.js以外の選択肢の検討に役立ちます
- [SWCとは？Rust製コンパイラの設定と採用判断を実装目線で解説](https://www.issoh.co.jp/tech/details/16019/)：Turbopackが内部で使う変換器を掘り下げています
- [esbuildとは？Go製の高速バンドラの使い方と採用判断を実装目線で解説](https://www.issoh.co.jp/tech/details/16017/)：Go製バンドラとの比較材料です

---

出典: [Turbopackとは：Next.js 16で既定になったRust製バンドラの設定と移行判断](<https://www.issoh.co.jp/tech/details/16015/>)（株式会社一創）
