Oxlint(オーエックスリント)は、Rustで書かれたJavaScript/TypeScript向けのリンターです。ESLint本体や関連プラグイン由来のルールとOxc独自ルールを合わせて871本提供し、既存のESLint設定を変換して移行できます。この記事では、2026年10月13日公開の1.88.0を対象に、ESLintとの違いを表で整理したうえで、VS Codeのソース約4,700ファイルを同じマシンで両方にかけた速度とメモリ、設定なしで実行したときの落とし穴、ESLintからの移行手順、Biomeとの選び分けを実行結果つきで解説します。
まとめ:OxlintとESLintの違いと選び方
- OxlintはOxcとは?Rust製JavaScriptツールチェーンの構成と使い方・SWCとの違いで解説しているOxcの一部で、リントだけを担います。読み方は公式の発音記号どおり「オーエックスリント」です。
- ルールは871本。公式一覧の既定有効は111本ですが、型情報が必要な15本を含み、型情報lintを有効にしない通常実行では96本です。ESLint本体・typescript-eslint・unicorn・React・Jest・Vitest・jsx-a11y・Next.jsなどのルールを移植しています。型情報を使わないルールは主にRust側で、型情報を使うルールはGo製のtsgolint側で実行します。
- VS Codeのソース約4,700ファイルでは、Oxlintが約1.4〜1.8秒・最大メモリ約265MB、ESLintが約237〜259秒・最大メモリ約1.2〜1.6GBでした(有効ルールの構成は同一ではありません)。
- 型情報が要るルールはoxlint-tsgolint(TypeScript 7のGo実装を使用)で、typescript-eslintの型情報ルール61本のうち59本に対応しています。
- 設定ファイルなしで実行すると違反はすべて警告扱いで、終了コードは0になります。CIに入れる前に
oxlint --initか--deny-warningsが必要です。 - 独自のESLintプラグインや、Vueのテンプレートを検査するルールに頼っている場合はESLintを残し、eslint-plugin-oxlintで重複ルールを止めて併用します。
以下、比較表・実測・導入手順・移行手順・Biomeとの違いの順に根拠を示します。
Oxlintの読み方と位置づけ
読み方は「オーエックスリント」
公式ドキュメントのOxlintのページは、名前の直後に発音記号 /oʊ-ɛks-lɪnt/ を示しています。O・Xをアルファベットで読む「オーエックスリント」が公式に沿った読み方です。日本語の記事や会話では「オックスリント」と呼ばれることもあり、検索ではどちらでも同じツールを指します。同じプロジェクトのフォーマッターOxfmtも /oʊ-ɛks-fɔːr-mæt/(オーエックスフォーマット)と表記されています。
Oxcのリンター部分を切り出したツール
OxlintはOxc(The JavaScript Oxidation Compiler)のパーサーの上に作られたリンターで、開発元はVoidZeroです。安定版1.0の発表は2025年6月10日で、npmの oxlint は2026年10月13日に1.88.0が公開されています。ほぼ毎週マイナー版が上がるため、記事やブログに書かれた「ルール数500超」「650超」といった数字はすぐ古くなります。導入前には npx oxlint --rules で手元の版のルール一覧を出すのが確実です。
OxlintとESLintの違いを7項目で比較
2026年10月17日時点の現行版で比べると、違いは次のとおりです。
| 項目 | Oxlint 1.88.0 | ESLint 10.13.0 |
|---|---|---|
| 実装言語 | Rust(ネイティブバイナリ) | JavaScript(Node.js) |
| ルール | 組み込み871本 | 本体のみ+プラグインで追加 |
| 設定なしの既定 | 通常実行はcorrectness 96本を警告 | 設定ファイル必須 |
| 設定ファイル | .oxlintrc.json(コメント可) | eslint.config.js(flat config) |
| 型情報ルール | oxlint-tsgolint(59/61本) | typescript-eslint(tsc を使用) |
| 独自プラグイン | jsPlugins(alpha) | JSで自由に追加 |
| Vue・Svelte・Astro | scriptブロックのみ | パーサー追加でテンプレートも |
実務で効くのは下の3行です。速度差は次の章で測りますが、乗り換えられるかどうかを決めるのは型情報・独自プラグイン・テンプレート検査の3点です。ESLint側の設定の書き方はESLintとは?VSCodeでの設定からflat config・Prettier連携まで解説【ESLint v10対応】で扱っています。
871ルールの内訳と通常実行で有効な96本
oxlint --rules -f json の出力を集計すると、871本の出どころはESLint本体187・unicorn138・typescript111・react85・vitest73・jest60・vue46・jsx-a11y36・import33・oxc独自27・jsdoc23・nextjs21・promise16・node11・react-perf4でした。カテゴリ別ではstyle279・correctness272・pedantic126・restriction103・suspicious65・perf15・nursery11です。
設定なしで有効になるのは、correctnessに属し、既定プラグイン(eslint・typescript・unicorn・oxc)に含まれる型情報不要の96本です。公式一覧の既定有効111本には、型情報lintを有効にして初めて動く15本も含まれます。「確実にバグ」と言えるものに絞っているため、ESLintの recommended から乗り換えると指摘が減ったように見えます。スタイル系を検査したい場合は categories で style や pedantic を明示的に有効にします。
型情報を使うルールはoxlint-tsgolintで59本
no-floating-promises のように型を見ないと判定できないルールは、別パッケージ oxlint-tsgolint を入れ、CLIの --type-aware またはルート設定の options.typeAware: true で有効にすると動きます。中身はGo製のtsgolintで、TypeScript 7のネイティブ実装(typescript-go)で型情報を作ります。公式の型情報lintのページは、typescript-eslintの型情報ルール61本のうち59本に対応と書いており、2026年7月22日にtsgolint v7とともに安定版扱いになりました。TypeScript 7の位置づけはTypeScript 7.0とは?Goネイティブ移植で型チェックを約10倍速くする仕組みを解説にまとめています。
npm i -D oxlint oxlint-tsgolint
# 新規導入で設定ファイルがない場合は、correctnessをerrorにする設定を作成
npx oxlint --init
npx oxlint --type-aware src
# src/a.ts:10:3: error typescript(no-floating-promises): Promises must be awaited, ...
注意点は、TypeScript 7で削除された設定がtsconfigに残っていると動かないことです。公式は baseUrl を未対応の例に挙げています。対処はtsconfigのbaseUrl非推奨(TS5101)の直し方とignoreDeprecations・TypeScript 7.0の削除エラーの手順で先にtsconfigを直すことです。
jsPluginsによるESLintプラグインの読み込み(alpha)
Oxlintに無いルールは、ESLint形式のプラグインを jsPlugins に登録して動かせます。公式のJS pluginsガイドはESLint v9以降のプラグインAPIとの互換を掲げつつ、状態をalphaとしています。次のような自作ルール(コメントにTODOを残さない)は、1.88.0でそのまま動きました。
// plug/my.js
export default {
meta: { name: "my" },
rules: {
"no-todo-comment": {
create(context) {
return {
Program() {
for (const c of context.sourceCode.getAllComments()) {
if (c.value.includes("TODO")) context.report({ loc: c.loc, message: "TODO を残さない" });
}
},
};
},
},
},
};
// .oxlintrc.json
{ "jsPlugins": ["./plug/my.js"], "rules": { "my/no-todo-comment": "error" } }
// 実行結果
// s/b.js:1:1: error my(no-todo-comment): TODO を残さない
JSプラグインはNode.js上で動くため、その分だけRust実装の速さは薄まります。社内ルールが数本なら移す価値がありますが、移行するプラグインが多い場合は、使用APIの対応状況と診断結果の一致を確認できるまで、ESLintを残して段階的に移行するのが妥当です。
Vue・Svelte・Astroはscriptブロックだけを検査
公式は .vue・.svelte・.astro を「scriptブロックだけをlintする」と明記しています。3種類のファイルのscript側に debugger、テンプレート側にNaNとの比較(Vueなら {{ value == NaN }})を入れて実行すると、検出されたのはscript(Astroはフロントマター)内の debugger だけで、テンプレートの比較は素通りしました。Oxlintの vue プラグイン(46ルール)もscript内で使えるルールに限られます。Vueのテンプレート構文を検査したいなら、eslint-plugin-vueを入れたESLintを残す必要があります。
VS Codeのソースで測った速度とメモリ
公式は「ESLintの50〜100倍速い」と書いていますが、ルール構成やマシンで倍率は変わります。そこで、同じマシンで同じディレクトリ群を対象に実行しました。ただし、対象拡張子や除外設定による実際の検査ファイルと、有効ルールの構成は一致させていません。対象はmicrosoft/vscodeの src/vs/base・src/vs/editor・src/vs/platform(コミット 44411589d2adc8e1b04b17bb74ca0d9fdfef8d7b、2026年10月16日)です。Oxlintが検査したのは4,696ファイルで、うちTypeScriptが4,674ファイル・約143万行です。
| 実行 | 有効ルール | 所要時間 | 最大メモリ |
|---|---|---|---|
| Oxlint 1.88.0(既定・全スレッド) | 96本 | 1.35〜1.84秒 | 約265MB |
Oxlint 1.88.0(--threads=1) |
96本 | 5.26〜5.42秒 | 約114MB |
| ESLint 10.13.0 | 69本 | 237.2〜259.2秒 | 約1.2〜1.6GB |
ESLint 10.13.0(--concurrency=auto) |
69本 | 206.2秒 | 約3.4GB |
計測に使った設定とコマンドは次のとおりです。Oxlintは通常3回・単一スレッド2回、ESLintは通常2回・並列1回を実行し、ESLintのキャッシュ(--cache)は使っていません。
// bench.eslint.mjs
import js from "@eslint/js";
import tseslint from "typescript-eslint";
export default tseslint.config(
{ files: ["src/**/*.ts"] },
js.configs.recommended,
...tseslint.configs.recommended,
);
// bench.oxlintrc.json は {}(既定のまま)
/usr/bin/time -l npx oxlint -c bench.oxlintrc.json src
/usr/bin/time -l npx oxlint -c bench.oxlintrc.json --threads=1 src
/usr/bin/time -l npx eslint -c bench.eslint.mjs src
/usr/bin/time -l npx eslint -c bench.eslint.mjs --concurrency=auto src
計測はmacOS(Intel Core i9-9880H・16スレッド・メモリ16GB)、Node.js 26.5.0で、/usr/bin/time -l の実時間と最大常駐メモリを取りました。Oxlintは設定を空にした既定の状態で、JSON出力が示す実行時の有効ルールは96本でした。ESLint側は @eslint/js のrecommendedとtypescript-eslint 8.71.2のrecommended(型情報なし)で、有効ルールは69本です。今回の異なる検査条件では、ESLintの最短237.2秒とOxlintの最長1.84秒を比べても、Oxlintの所要時間は約129分の1でした。ただし、ルール数だけでは検査範囲や処理量の大小を比較できません。
単一スレッドでも5秒台でした。ただし、ルール構成や解析処理が異なるため、この比較だけでは速度差のうちRust実装による寄与を切り分けられません。ESLint 10の --concurrency=auto でワーカーを並列に動かしても206.2秒で、短縮は1割強にとどまり、最大メモリは約3.4GBに増えました。現在のリポジトリでESLintが数秒で終わり、待ち時間が問題になっていないなら、速度だけを理由に乗り換える必要はありません。差が効くのは、CIのlintが分単位でかかっている大きなリポジトリや、pre-commitで毎回待たされている場合です。
Oxlintを導入する手順
Oxlintのインストールと初回実行
Node.jsのプロジェクトなら開発依存に入れて、そのまま実行できます。設定ファイルが無くても動きます。
npm i -D oxlint
npx oxlint # カレント以下を検査
npx oxlint src test # パスを指定
npx oxlint --rules # この版のルール一覧
package.jsonの scripts に "lint": "oxlint" を足しておくと、CIやpre-commitから同じコマンドで呼べます。Vite系のツールチェーンでまとめて扱いたい場合は、公式が統合ツールとして案内しているVite+とは?vpコマンドの使い方と1.0の中身・既存Vite案件の移行手順を実装目線で解説も候補になります。
設定なし実行は警告だけで終了コード0
最初につまずくのがここです。設定ファイルなしで次のファイルを検査すると、未使用変数・NaNとの比較・debugger・typeofの綴り違いの4件が出ますが、すべてwarningで、終了コードは0でした。CIに npx oxlint だけを書くと、明らかなバグがあってもジョブは成功します。
const unused = 1;
export function check(x: number) {
if (x == NaN) {
debugger;
}
return typeof x === "nubmer";
}
$ npx oxlint src
src/a.ts:1:7: warning eslint(no-unused-vars): Variable 'unused' is declared but never used. ...
src/a.ts:3:12: warning eslint(use-isnan): Checking equality with NaN will always return false ...
src/a.ts:4:5: warning eslint(no-debugger): `debugger` statement is not allowed ...
src/a.ts:6:23: warning eslint(valid-typeof): Invalid `typeof` comparison value. ...
$ echo $?
0
対処は2つあります。npx oxlint --init で設定ファイルを作ると "categories": { "correctness": "error" } が書かれ、同じ4件がerrorになって終了コード1で止まります。設定を作らずに済ませるなら --deny-warnings を付けると、警告が1件でもあれば終了コード1になります。
.oxlintrc.jsonの書き方とpluginsの上書き
--init が作る設定は次の形です。コメントを書けるJSONで、$schema を指定するとエディタで補完が効きます。TypeScriptで書く oxlint.config.ts も読めますが、ヘルプには実験的機能でNode.js経由の実行が必要と書かれています。
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["typescript", "unicorn", "oxc"],
"categories": { "correctness": "error" },
"rules": {},
"env": { "builtin": true }
}
plugins を書くと既定のプラグイン一式が置き換わる点に注意してください。Reactのルールを足すつもりで "plugins": ["react"] だけを書くと、unicornが外れ、arr.length === 0 || arr.every(Boolean) を指摘する unicorn(no-useless-length-check) が出なくなりました。["react", "typescript", "unicorn", "oxc"] のように既定分も並べると元に戻ります。
GitHub Actionsとpre-commitへのOxlintの組み込み
公式のCIガイドどおり、依存を入れてlintスクリプトを呼ぶだけです。GitHub Actions上ではOxlintが環境を検出して、指摘をプルリクエストの該当行に注釈として出します。
name: Lint
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
oxlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: lts/*
cache: npm
- run: npm ci
- run: npm run lint
actions/setup-node の入力とキャッシュの指定はactions/setup-nodeとは|v7の入力・キャッシュ設定とv5以降の既定変更で確認できます。コミット前に変更ファイルだけを検査するには、Gitのpre-commitフックからlint-stagedを呼び出す設定も必要です。そのうえで、lint-stagedの設定に "*.{js,jsx,ts,tsx,mjs,cjs}": "oxlint" を書きます。GitLabでは --format=gitlab でCode Quality形式のレポートを出せます。lintをCI/CDの品質ゲートとして設計し直す場合は、DevOps・CI/CD導入支援でパイプライン全体の見直しから相談を受けています。
ESLintからOxlintへ移行する手順
@oxlint/migrateによるflat configの変換
@oxlint/migrate は、ESLintのflat config(eslint.config.*)を読み込んで、Oxlintが対応しているルールを .oxlintrc.json に書き出します。@eslint/js・typescript-eslint・eslint-plugin-react-hooks・eslint-plugin-react-perfのrecommendedに独自ルール2本を足した設定で実行すると、次の結果でした。
$ npx @oxlint/migrate --details
✨ .oxlintrc.json created with 102 rules.
Skipped 6 rules:
- 2 Nursery
- no-undef
- no-useless-assignment
- 4 Unsupported
- no-dupe-args: Superseded by strict mode.
- no-octal: Superseded by strict mode.
- react-hooks/config: ...
- react-hooks/gating: ...
書き出された設定は "categories": { "correctness": "off" } になっており、ESLintで有効だったルールだけが動く形です。react-hooks/rules-of-hooks は react/rules-of-hooks に、React Compiler由来の purity や refs も react/purity などに置き換えられていました。ESLint v8以前の .eslintrc を使っている場合は、先にflat configへ移してから実行します。
eslint-plugin-oxlintによる重複ルールの無効化と併用設定
大きなリポジトリでは、公式も「先にOxlintを実行し、重複するルールを無効にしたESLintを後で実行する」段階移行を勧めています。ESLint側でOxlintと同じルールを止めるのが eslint-plugin-oxlint です。次の設定を追加する前に、npm i -D eslint-plugin-oxlint でインストールします。
// eslint.config.mjs
import oxlint from "eslint-plugin-oxlint";
export default [
// ...既存の設定
...oxlint.buildFromOxlintConfigFile("./.oxlintrc.json"),
];
// package.json
"lint": "oxlint && eslint"
buildFromOxlintConfigFile は .oxlintrc.json を読み、Oxlintが受け持つルールだけをESLint側でoffにします。上の移行結果から作ると108本がoffになりました。flat/recommended は249のルール名をまとめてoffにしますが、Oxlintの既定では無効なReactなどのルールも含みます。検査漏れを防ぐため、設定ファイルを作り、実際にOxlintで有効にしたルールに合わせてESLint側を無効化してください。この形ならESLintに残るのはOxlintに無いルールだけなので、ESLintの実行時間も縮みます。
eslint-plugin-react-perfからOxlint内蔵ルールへの置き換え
Reactの再レンダーを招くpropsを検出するeslint-plugin-react-perfは、npmの最新3.3.3(2024年10月18日公開)のpeerDependenciesがESLint 9までで、ESLint 10.13.0の環境に npm i すると依存解決エラーで止まりました(--legacy-peer-deps を付ければ入ります)。Oxlintには同じルールが react-perf プラグインとして4本内蔵されています。
{
"plugins": ["react", "react-perf", "typescript", "unicorn", "oxc"],
"rules": {
"react-perf/jsx-no-new-object-as-prop": "error",
"react-perf/jsx-no-new-function-as-prop": "error",
"react-perf/jsx-no-new-array-as-prop": "error"
}
}
// <Row style={{ color: "red" }} onClick={() => ...} data={[1, 2]} /> の3か所を検出
4本目の jsx-no-jsx-as-prop を含め、どれもperfカテゴリで既定はoffです。--react-perf-plugin を付けるだけではルールは有効にならず、上のように個別に指定するか、categories で perf を有効にします。
OxlintとBiomeの違いと選び分け
同じRust製でも、Biomeはリンターとフォーマッターを1つにまとめたツールで、Oxlintはリンター単体です(フォーマッターは別ツールのOxfmt 0.73.0)。Biomeの導入と設定はBiome v2とは?最新2.5系の導入・biome.json設定とESLint/Prettier移行にまとめています。
| 項目 | Oxlint 1.88.0 | Biome 2.5.15 |
|---|---|---|
| 担当範囲 | リントのみ | リント+フォーマット |
| リントルール数 | 871本 | 557本(うちnursery 130) |
| 型情報 | tsgolint(TypeScript 7) | 独自の型推論(tsc不要) |
| 拡張 | ESLint形式のjsPlugins | GritQLプラグイン |
| ESLint設定の移行 | @oxlint/migrate | biome migrate eslint |
Biomeのルール数は、2.5.15の設定スキーマで各グループのルールを数え、recommended と preset を除いた値です。型情報の取り方がいちばん大きな違いで、Biomeの noFloatingPromises(nursery)は、tsconfig.jsonを置かないディレクトリでも、検証用に用意した、Promiseを返す load() をawaitせずに呼ぶコードを検出しました。TypeScriptコンパイラを呼ばずにBiome自身が型を推論するためです。一方、Oxlintはtsgolint経由でTypeScriptの型チェッカーが作った型情報を使い、ルールのオプションもtypescript-eslintと同じものを受け付けます。既存のtypescript-eslintの設定と同じ判定を保ちたいなら、Oxlintの方が移しやすい構成です。
選び方ははっきりしています。新規プロジェクトでPrettierもまとめて置き換え、設定ファイルを1つにしたいならBiome。既存のESLint設定を引き継ぎたい、typescript-eslint由来の型情報ルールや設定を引き継ぎたい、Reactやテストのプラグインルールを多く使っているならOxlintです。Prettierとの関係を整理したい場合はPrettierとは?意味・読み方からコマンド・設定・ESLintとの違いまでも参照してください。
Oxlintへ乗り換えずESLintを残す条件
次のどれかに当てはまるなら、ESLintを残します。速度改善が必要な場合はOxlintとの併用を検討しますが、ESLintが数秒で終わり待ち時間が問題でなければ、Oxlintの追加も不要です。
- Vueのテンプレートやeslint-plugin-vueの
vue/テンプレート系ルールに頼っている(Oxlintはscriptブロックしか見ない) - 社内製ESLintプラグインが多い、または型情報を使う独自ルールを書いている(jsPluginsはalpha)
- tsconfigに
baseUrlなどTypeScript 7で消えた設定が残り、すぐには直せない(型情報lintが動かない) - リポジトリが小さく、ESLintでも数秒で終わっている(乗り換えの手間に見合う短縮が無い)
逆に、CIのlintが1分を超えていて、使っているプラグインがOxlintの内蔵プラグイン一覧(React・Jest・Vitest・jsx-a11y・import・Next.js・JSDoc・promise・node)に収まっているなら、eslint-plugin-oxlintで併用を始めます。ESLint側に残るルールがゼロになったら、対象ファイル・ルールオプション・診断結果の差分を確認し、必要な検査を維持できる場合にESLintを外します。静的解析で拾えない問題の切り分けは静的コード解析の誤検知と限界|レビュー・テストとの責任分担で整理しています。
よくある質問
Oxlintでコードの整形(フォーマット)はできますか?
Oxlintはリント専用で、整形はしません。--fix は、安全な自動修正を適用します。公式一覧の334本には提案や危険な修正を提供するルールも含まれるため、すべてを --fix だけで修正できるわけではありません。整形には同じOxcプロジェクトのOxfmt(npmの最新は0.73.0)を使います。公式はOxfmtをPrettier互換の手順で使える専用フォーマッターと位置づけ、Prettierのプラグインの挙動にまだ依存している場合はPrettierに残るよう案内しています。
eslint-plugin-react-hooksのルールはOxlintで使えますか?
使えます。rules-of-hooks と exhaustive-deps は react プラグインのルールとして内蔵されています。React Compiler由来のルール(purity・refs・set-state-in-effect など)も react/ の名前で実装されていますが、公式は実験的で既定offとしているため、plugins に react を入れて個別に有効にします。@oxlint/migrateを通すと、ESLint側の設定から自動で書き換えられます。
Next.jsやJSDocのルールもありますか?
あります。nextjs プラグインは@next/eslint-plugin-next由来の21本、jsdoc プラグインは23本です。どちらも既定では無効なので、.oxlintrc.json の plugins に既定の typescript・unicorn・oxc と並べて追加します。CLIで試すだけなら --nextjs-plugin や --jsdoc-plugin でも有効になります。
ESLintの無効化コメントはそのまま効きますか?
効きます。// eslint-disable-next-line no-debugger の形のコメントで、次の行のdebuggerの指摘が消えることを1.88.0で確かめました。Oxlint独自の oxlint-disable・oxlint-disable-line・oxlint-disable-next-line も使えます。使われていない無効化コメントは --report-unused-disable-directives で洗い出せます。
モノレポでパッケージごとに設定を分けられますか?
分けられます。Oxlintは検査する各ファイルから最も近い .oxlintrc.json(または oxlint.config.ts)を使います。ただし親の設定とは自動で合成されません。ルート側で correctness をerrorにし、packages/web に no-console だけを書いた設定を置くと、web配下の debugger はwarningに戻りました。子の設定に "extends": ["../../.oxlintrc.json"] を書くと、ルートの設定を引き継いでerrorになります。