SWCとは?Rust製コンパイラの設定と採用判断を実装目線で解説
SWCは、JavaScriptとTypeScriptを変換・圧縮するためにRustで書かれたコンパイラです。名前はSpeedy Web Compilerの略で、npm registryで2026年8月1日に確認した@swc/coreのlatestは1.15.47。Next.jsが内部の変換基盤として採用したことで一気に広まり、いまではJestやwebpackの前処理、Turbopackのような上位ツールの部品としても動いています。この記事では、SWCの守備範囲、.swcrcの書き方、Next.jsやJestでの組み込み方、型検査を持たない前提の運用、そして受託開発で採用してよい条件までを実装目線で扱います。
まとめ:SWCを採用してよい条件と見送る線引き
結論を先に置きます。Babelの変換が遅くてCIやFast Refreshが詰まっている、かつ使っているBabelプラグインがpreset-env・preset-typescript・preset-reactと標準的な提案構文までなら、SWCへの置き換えはほぼそのまま通ります。CLIがBabelの代替として設計されているため、npx babelをnpx swcへ差し替える形から始められる点も移行コストを下げてくれる要素。Next.jsを使っているなら、v12以降は何も設定しなくてもSWCが既定で動いています。
見送る判断が要るのは3つの場合です。第一に、自社で書いた独自のBabelプラグインやマクロ系の変換に依存している構成。SWCのプラグインはRustをWasmへ固めて渡す方式で、JavaScriptで書いたBabelプラグインをそのまま持ち込めません。第二に、変換の副産物として型情報を使う構成。SWCは型を落とすだけで検査はしないため、tscを別プロセスで走らせる前提になります。第三に、変換の細部まで挙動を固定したい長期保守案件。この3つに当たるなら、Babelを残すか、変換だけSWC・特殊処理だけBabelという二段構えを検討してください。
SWCの定義|Speedy Web Compilerが担う変換と圧縮の範囲
まず、SWCが何をするものなのかを守備範囲から押さえます。ここを曖昧にしたまま導入すると、バンドラと役割が重なって二重に処理する構成になりがちです。
Speedy Web Compilerという名前が示す守備範囲と提供パッケージ
SWCは公式に「次世代の高速な開発ツールのための拡張可能なRustベースのプラットフォーム」と位置づけられています。単体のツールというより、変換・圧縮・バンドルといった処理を呼び出せる土台という立て付け。実際の利用は、Next.jsのような上位ツールがSWCをRustのクレートとして組み込む形か、npmパッケージ経由でNode.jsから叩く形のどちらかになります。
npmから使う場合の入口は@swc/coreで、コマンドラインから叩く@swc/cliと組み合わせるのが基本形です。ほかにJest向けの@swc/jest、webpack向けのswc-loader、ブラウザやEdge環境向けの@swc/wasm、HTML圧縮の@swc/htmlが公式から出ています。バイナリはMac・Linux・Windows・Alpine・Androidの各アーキテクチャ向けにビルド済みのものが降りてくるため、Rustツールチェーンを自分で入れる必要はありません。
Babelの17倍という速度差の出どころと数字を読むときの前提
速度の話でよく引かれる「Babelの17倍」という数字は、Next.js公式ドキュメントがNext.js Compilerの説明で挙げているものです。同じ文脈で、SWCへ切り替えた結果としてFast Refreshが約3倍、ビルドが約5倍という数字も出ています。圧縮側についても、v13で既定になったSWCのミニファイアはTerserより7倍速いと明記されています。
ただし、これらはNext.jsという特定の構成で測った値です。手元のプロジェクトで同じ倍率が出るとは限りません。変換対象のファイル数、TypeScriptの型検査を別に走らせるかどうか、CIのコア数で結果は変わります。移行の可否を判断するなら、公称値ではなく自分のリポジトリでBabelとSWCの両方をCIに通し、実測で比べるほうが確実です。
1.15系という版番号とWasmプラグイン互換が変わった転換点
版番号は1.x系に到達しており、npm registryで2026年8月1日に確認したlatestは1.15.47でした。0.x系のesbuildと違い、パッチ更新で破壊的変更が入る前提を置かなくてよい点は運用上の差です。
この1.15系には、プラグイン利用者にとって大きい変更が入っています。公式のプラグイン互換ドキュメントによると、@swc/core v1.15.0以降、Wasmプラグインは版を跨いである程度動くようになりました。シリアライズ方式をrkyvからCBORへ切り替え、フィールドのメモリレイアウトをメタデータとして記録する方式にしたことと、ASTのenumにUnknownのバリアントを足して未知のデータを受け流せるようにしたことが理由。以前はコアとプラグインの版を厳密に合わせる必要があり、コアを上げるとプラグインが動かなくなる事故が起きていました。ただし公式も、フィールドの削除や型の変更に起因する非互換までは解消しないと断っています。
SWCの導入手順と.swcrcに書く設定項目の最小構成を押さえる
次に、実際に動かす手順を確認します。設定ファイルは.swcrc1枚で、Babelのようにプラグインを並べる書き方ではありません。
npmでの導入から1コマンドでトランスパイルするまでの最短手順
導入はnpmが基本で、環境に合うネイティブバイナリが自動で選ばれます。CLIとコアの2つを開発依存に入れれば、その場でディレクトリ単位の変換が動きます。
npm install -D @swc/cli @swc/core
npx swc ./src -d dist
この時点では.swcrcがなくても動きますが、出力はes5相当の既定値になります。TypeScriptやJSXを含むプロジェクトでは、パーサーの指定がないと構文エラーで止まるため、実務では設定ファイルを先に置くほうが早いでしょう。
TypeScriptとReactを通す.swcrcの最小構成と各項目の意味
設定はプロジェクト直下の.swcrcに置きます。TypeScript+Reactの構成なら、以下がそのまま出発点になります。
{
"$schema": "https://swc.rs/schema.json",
"jsc": {
"parser": { "syntax": "typescript", "tsx": true },
"target": "es2022",
"transform": { "react": { "runtime": "automatic" } }
},
"module": { "type": "es6" },
"minify": false
}
jsc.parser.syntaxはecmascriptかtypescriptの二択で、ここが入力の解釈を決めます。JSXを含む場合、TypeScriptならtsx、素のJavaScriptならjsxを真にする点が引っかかりやすいところ。デコレータを使うならdecoratorsを足します。jsc.transform.react.runtimeをautomaticにすると、React 17以降のJSX変換になり、各ファイルのimport Reactが不要になります。
moduleのtypeとjsc.targetを決めるときの判断材料
module.typeは出力するモジュール形式の指定で、commonjs・es6・amd・umdなどが選べます。Jestで使うならcommonjs、バンドラに食わせるならes6が基本線。ここを間違えると、実行時にrequire is not definedのような形で表面化します。
| 設定項目 | 決め方の基準 |
|---|---|
| jsc.parser.syntax | 入力がTSかJSかで選ぶ |
| jsc.parser.tsx | TSXを含むなら真にする |
| jsc.target | 対応ブラウザの下限で決定 |
| module.type | Jestはcommonjs・他はes6 |
| minify | バンドラ側と重複させない |
jsc.targetは出力するECMAScriptのバージョンで、既定はes5です。サポート対象ブラウザの下限から逆算して決めます。minifyを真にすると圧縮まで担いますが、バンドラ側でも圧縮している構成では二度手間になるため、どちらか一方に寄せる整理が要ります。
Next.jsとJestとwebpackでSWCが使われている場所
SWCを単体で導入する場面より、既存のツールの内側で動いているものを設定するほうが実務では多くなります。代表的な3つを順に見ます。
Next.js Compilerの守備範囲とcompilerオプションの設定
Next.js Compilerは、Rustで書かれSWCを使う変換基盤です。個々のファイルに対するBabelと、出力バンドルの圧縮に対するTerserの両方を置き換える役割を持ち、v12以降は既定で有効になっています。圧縮側はv13から既定で、v15ではswcMinifyフラグ自体が削除されたため、圧縮の細部を設定で変える余地はなくなりました。
変換の指定はnext.config.jsのcompilerフィールドで行います。styled-components、Relay、Emotion、console呼び出しの除去、data-test系属性の除去、ビルド時の変数置換といった、もともとBabelプラグインで実現していた変換が移植済みです。
module.exports = {
compiler: {
styledComponents: true,
removeConsole: { exclude: ['error'] },
define: { 'process.env.MY_FLAG': 'on' },
},
transpilePackages: ['@acme/ui'],
}
モノレポのローカルパッケージやnode_modules内の依存を変換したい場合はtranspilePackagesを使います。かつてのmodularizeImportsはv13.5でoptimizePackageImportsに置き換わっており、新規に書くならそちらです。Next.js 16.2.12時点のバンドラ側の状況は、Turbopackとは?Next.js 16で既定になったRust製バンドラの設定と移行判断に整理してあります。
.babelrcがあるとSWCが無効になる仕組みと移行時の注意
ここが移行時に最も踏みやすい落とし穴です。Next.js公式は、アプリケーションに.babelrcが存在する場合、個々のファイルの変換は自動的にBabelへ退避すると明記しています。既存のBabelプラグインを使っているプロジェクトとの後方互換を保つための仕様。
つまり、リポジトリのどこかに古い.babelrcが残っているだけで、SWCの速度は一切効きません。ビルドが遅いという相談を受けたとき、まず確認すべきはこのファイルの有無です。移行するなら、Babel設定に書かれた変換がcompilerフィールドで代替できるかを1つずつ突き合わせ、全部移せた時点で.babelrcを消す手順になります。移せないプラグインが1つでも残るなら、無理に消さずBabelを残す判断のほうが安全側でしょう。
JestとwebpackでBabelをSWCへ置き換える具体的な手順
Jestはbabel-jestを@swc/jestへ差し替えるだけで動きます。npm registryで2026年8月1日に確認した@swc/jestのlatestは0.2.39。.swcrcを既定で読むため、変換設定を二重に書く必要はありません。
{
"transform": {
"^.+\\.(t|j)sx?$": ["@swc/jest", {}]
}
}
webpackならswc-loader(同日時点で0.2.7)をbabel-loaderの位置に置きます。なお、Next.jsでJestを使う場合はnext/jestというヘルパーが用意されており、CSSや画像のモック、環境変数の読み込み、node_modulesの除外まで面倒を見てくれるため、自前でtransformを書くより手数が減ります。
SWCが担当しない領域と型検査を別プロセスで走らせる運用の設計
速度の代償として、SWCが引き受けない処理があります。ここを理解せずに導入すると、CIをすり抜けたエラーが本番で出ます。
型を落とすだけで検査はしない前提とtscを併走させる構成の組み方
SWCはTypeScriptの型注釈を取り除いて出力するだけで、型が正しいかどうかは見ていません。@swc/jestの説明が「型検査なしのbabel-jest・ts-jest代替」と書かれているのはこのため。ファイル単位で独立して変換できるからこそ速い、という設計上のトレードオフです。
運用としては、変換はSWC、型検査はtsc --noEmitという二本立てにします。ローカルではエディタのTypeScript言語サーバが型を見るため気づきにくいものの、CIには型検査のジョブを必ず並べてください。変換ジョブと型検査ジョブを並列に走らせれば、全体の待ち時間はtsc側に律速されるだけで済みます。同じ構造は、型を持たない他の高速変換器でも共通です。守備範囲の切り方が近い例として、esbuildとは?Go製の高速バンドラの使い方と採用判断も合わせて読むと違いが立体的になります。
Wasmプラグインの立ち位置と1.15.0以降の版跨ぎ互換の話
独自変換を足したい場合、SWCではRustで書いたコードをWasmへコンパイルしてプラグインとして渡します。Next.jsからはexperimental.swcPluginsで読み込む形で、公式が実験的機能と位置づけている段階。Babelプラグインの資産をそのまま移植できない点が、移行判断で一番重い制約になります。
前述のとおり、v1.15.0以降はプラグイン側がswc_coreの47以降に依存し、swc_ast_unknownのcfgフラグを有効にしたうえでUnknownバリアントを処理していれば、コアの版を跨いでも動くようになりました。裏を返すと、その条件を満たしていない古いプラグインは従来どおり版の縛りを受けます。サードパーティのSWCプラグインを本番に載せるなら、対応状況を確認したうえで@swc/coreの版を固定する運用が現実的です。実例として、React Compilerとは?自動メモ化の仕組みと導入方法で扱った自動メモ化も、SWC側のプラグインとして組み込まれる形を取っています。
esbuildやBabelやOxcとの違いと受託開発での使い分け
最後に、似た立ち位置のツールとの違いを整理します。速さだけで並べると選び分けを誤るため、守備範囲と拡張性の軸で比べます。
SWCとesbuildとBabelとOxcの守備範囲を一覧で比較する
| ツール | 実装言語 | 拡張の方式 | 主な使いどころ |
|---|---|---|---|
| SWC | Rust | Wasmプラグイン | Next.jsの変換基盤 |
| esbuild | Go | JSプラグイン | バンドルと圧縮 |
| Babel | JavaScript | JSプラグイン | 独自変換と提案構文 |
| Oxc | Rust | Rust内蔵 | Lintを含む一式 |
SWCとesbuildは、変換の速さを取る代わりに型検査を持たない点で同じ性格です。違いはバンドルの扱いで、esbuildはバンドラとして完成度が高い一方、SWCは変換器としての性格が強く、バンドルは上位ツールに任せる構成が主流。Babelは速度で劣るものの、JavaScriptでプラグインを書ける拡張性という一点で今も代えが利きません。Rust製ツールチェーンとしての対抗馬はOxcとは?Rust製の高速JavaScript/TypeScriptツールチェーンで、こちらはLintまで含めて一式で揃える方向を取っています。
TurbopackやRspackの内部部品として使われている側面
SWCを直接設定する機会がなくても、実は使っているというケースは少なくありません。Next.jsの既定バンドラであるTurbopackは、内部の変換と古い構文へのダウンレベルをSWCに任せています。Parcelやかつてのdenoも同様にSWCを取り込んでおり、公式はVercel・ByteDance・Tencent・Shopifyといった採用例を挙げています。
Vite系でも同じ構図が見られます。@vitejs/plugin-react とは?v6の導入設定とplugin-react-swcとの違いで扱ったとおり、React向けプラグインにはBabel版とSWC版の系統があり、どちらを選ぶかで変換の速度と拡張性が入れ替わります。つまりSWCの設定知識は、SWCを直接入れる場面より、上位ツールの選択肢を読み解く場面で効いてくるわけです。
受託開発でSWCを採用してよい3条件と見送るべき場面の切り分け
受託の現場で判断するなら、次の3条件が揃うときにSWCを選んで問題ありません。第一に、Next.jsを使っている(この場合は既定なので選択の余地すらない)。第二に、Babel設定が標準的なプリセットの範囲に収まっている。第三に、CIにtsc --noEmitのジョブを並べる運用を組める。
逆に見送るのは、独自のBabelプラグインが業務ロジックに食い込んでいる場合と、長期保守で変換結果の完全な再現性を契約上求められる場合です。前者は移植コストがRustの学習コストごと乗ってきます。後者はWasmプラグインが実験的機能である以上、リスクを負う理由が薄いでしょう。業務用・Webアプリ開発では、こうしたビルド基盤の選定から移行手順の設計、CIの組み直しまでを含めて相談を受けています。既存プロジェクトのビルドが遅く、どこから手を付けるか決めかねている場合は、まず.babelrcの有無とCIの内訳を洗い出すところから始めてください。
よくある質問
SWCとBabelはどちらを選ぶべきですか?
標準的なプリセットしか使っていないならSWCで問題ありません。判断の分かれ目は独自プラグインの有無です。JavaScriptで書いたBabelプラグインをそのまま持ち込めないため、業務固有の変換が入っているプロジェクトではBabelを残すか、二段構えにする設計が要ります。
SWCを入れると型エラーは検出されなくなりますか?
ビルド時には検出されません。SWCは型注釈を取り除くだけで検査はしないためです。CIにtsc --noEmitのジョブを別途並べて、型検査だけを担当させる構成にしてください。変換ジョブと並列に走らせれば、全体の所要時間はほとんど増えません。
Next.jsでSWCを有効にする設定は必要ですか?
Next.js v12以降は既定で有効なので、設定は不要です。むしろ注意すべきは無効化される条件のほうで、プロジェクトに.babelrcがあると個々のファイルの変換はBabelへ退避します。速度が出ないときは、まずこのファイルが残っていないかを確認しましょう。
.swcrcとnext.config.jsの設定は併用できますか?
Next.js公式ドキュメントは、変換の指定をnext.config.jsのcompilerフィールドで行う方法のみを案内しています。Next.jsの内側の変換を調整したいならcompiler側に書いてください。.swcrcが効くのは、CLIや@swc/jestのようにSWCを直接呼び出す経路です。
SWCのWasmプラグインは本番で使えますか?
Next.jsからの読み込みは実験的機能の扱いです。v1.15.0以降でコアとの版跨ぎ互換が入り、以前より壊れにくくはなりました。それでも本番に載せるなら、プラグインがswc_core47以降に対応しているかを確認したうえで、@swc/coreの版を固定する運用にしておくのが無難です。