Oxlint vs ESLint: CIにはどちらのJS linterか
Oxlint(Oxcプロジェクト由来)はESLintより桁違いに速く動作するRustベースのlinterで、ESLintは完全なルールとプラグインのエコシステムを保ちます。
ESLintは最大のルールとプラグインのセットを持つ標準的なJavaScript/TypeScriptのlinterです。OxlintはRustベースの速度重視のlinterで、ほぼゼロ設定で多くの一般的なルールをカバーし、時間とともにカバレッジを改善しています。
Oxlint vs ESLint at a glance
| Oxlint | ESLint | |
|---|---|---|
| 実装 | Rust | JavaScript |
| 速度 | 極めて高速 | より遅い |
| ルールカバレッジ | 多くの一般的なルール、成長中 | 完全、最大 |
| プラグインエコシステム | 限定的、成長中 | 最大 |
| 設定 | ほぼゼロ | 柔軟 |
| 型を意識したlint | あり。tsgo (TypeScript 7) 経由 | あり。typescript-eslint経由 |
| 設定形式 | 独自設定、ESLint風 | v9とv10のflat config (eslint.config.js) |
| Autofix | あり (--fix) | あり (--fix) |
| エディタ統合 | 利用可能 | 普遍的 |
| drop-inな置き換え | まだ不可 | 該当なし |
CIでは
OxlintはESLintのごく一部の時間で巨大なコードベースをlintできるため、高速な第一段階のgateとして魅力的です。まだESLintのすべてのルールやプラグインをカバーしていないため、多くのチームは速度のためにOxlintを実行し、Oxlintに欠けているルールのためにESLintを残します - しばしばpushごとにOxlint、より完全なESLintパスをより低頻度で実行します。カスタムまたはframework固有のプラグインに依存する場合、ESLintは依然として不可欠です。
| ESLint lint step | Oxlint at 50x | Oxlint at 100x |
|---|---|---|
| 10 seconds | 0.2 s | 0.1 s |
| 60 seconds | 1.2 s | 0.6 s |
| 3 minutes | 3.6 s | 1.8 s |
| 8 minutes (large monorepo) | 9.6 s | 4.8 s |
両者を併用する
Oxlintを高速な事前チェックとして、ESLintをそれがカバーしないルールのために実行します。lintはCPUバウンドなので特別なcacheは不要です。どちらもmanaged runnerで動作し、高速なmanaged runnerは大きなリポジトリでのESLintパスを短縮します。
- What ports cleanly: core correctness rules, TypeScript rules, React hooks and JSX rules, and the common test-framework plugins.
- What does not: your own in-house rules, and smaller community plugins nobody has ported.
- Rule *names* mostly match ESLint, so disable comments and config intent carry over more easily than a rewrite would suggest.
型を意識したlintが最新かつ最大の変化
型を意識したルールとは、構文木だけでなく型チェッカーを必要とするものです。未処理のpromise、安全でない any の伝播、誤用されたpromiseなどです。従来これらはtypescript-eslint経由のESLint専用であり、完全な型チェックを要するためどの設定でも最も遅いルールでもありました。
- oxlintはTypeScriptのGo移植 (tsgo、TypeScript 7) と統合することで型を意識したlintに対応し、未処理promiseの検出などが可能になりました。
- これにより、TypeScriptのコードベースがoxlintをそもそも検討できなかった最大の技術的理由がなくなりました。
- 同時にここは最も速く動いている領域なので、同等だと仮定せず、実際に依存しているルールに対する現在の対応状況を確認してください。
本当の障害: カスタムpluginがアルファ
社内ルールを保守しているなら、判断はこれで決まります。oxlintはESLintのpluginエコシステムと互換のJS pluginに対応していますが、その対応はアルファと明記されています。アルファはlintの実験には十分でも、マージを止めるゲートには不十分です。
- カスタムルールがなく主流のpluginだけのリポジトリなら、今日でも移行できることが多いです。
- アーキテクチャ上の制約を表現する社内ルールがあるリポジトリは、そのルールに限ってESLintを残すべきです。
- ネイティブ (Rust) のpluginは安定していますが、Rustを書くことになり、JSのルールを保守するのとは別の話になります。
大規模リポジトリが実際に採る方法: 両方使う
どちらかを選ぶのではなく、oxlintを高速な事前フィルタとして走らせ、oxlintがまだ扱えないルールにESLintを使います。重要なところで速いフィードバックループを得つつ、必要なところで完全なルール網羅を保てます。
# package.json scripts
{
"scripts": {
"lint:fast": "oxlint",
"lint:full": "eslint .",
"lint": "oxlint && eslint ."
}
}
# .github/workflows/ci.yml
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: npm }
- run: npm ci
# Fails in about a second on the 865 rules oxlint covers,
# so the slow full pass only runs on code that already passes.
- run: npx oxlint
- run: npx eslint .完全移行が理にかなう場合
- ESLintのpluginとカスタムルールを棚卸しし、それぞれをoxlintのルール一覧と突き合わせます。
- カスタムなものが出てこなければ、CIで数週間
oxlintをESLintと並走させ、検出結果を差分で比較します。 - 食い違いはすべて調べてください。同名のルールでも端の挙動が異なることがあり、その端こそ静かな挙動変化が潜む場所です。
- 信頼できたら高速なパスをpre-commitフックに移し、lint失敗がそもそもCIに届かないようにします。
- 差分が空になり、設定のどこもアルファのJS plugin対応に依存しなくなって初めて、ESLintを退役させてください。
The switching cost is mostly in the parts nobody lists
- Assertions and mocks usually port mechanically when the target implements a compatible API; custom transformers and framework plugins do not.
- Snapshot formats differ between runners, so plan to regenerate and review rather than port.
- Run both suites in parallel in CI for a period and diff the results. A migration that changes which tests fail is not a migration, it is a regression you have not found yet.
- Coverage numbers move on a runner change even when the tests do not, because instrumentation differs. Re-baseline any coverage gate deliberately.
The verdict
超高速なlintパスが欲しく、重要なルールがカバーされているなら: Oxlint(多くの場合ESLintと併用)。完全なルールとプラグインのエコシステムが必要なら: ESLint。多くのチームは両者を組み合わせます - 速度のためのOxlint、カバレッジのためのESLintです。
よくある質問
oxlintはESLintのdrop-inな置き換えですか?
oxlintはESLintよりどれだけ速いですか?
oxlintは型を意識したlintに対応していますか?
oxlintにはいくつルールがありますか?
oxlintとESLintを同時に使えますか?
oxlint を走らせて違反の大半を約1秒で表面化させ、その後oxlintが扱わないルールのために eslint . を走らせます。網羅性を損なわずに失敗レイテンシが改善します。本番でoxlintを使っているのは誰ですか?
oxlintはautofixに対応していますか?
eslint --fix と同じ形の oxlint --fix があります。はるかに高速なため、遅いESLintのパスではしばしば現実的でない「保存時のautofix」が実用になります。