Oxlintへの移行方法【まだESLint使ってるの?】

Oxlintへの移行方法【まだESLint使ってるの?】

西原月熙
西原月熙14分で読めます
はてなブックマーク

はじめに

こんにちは、株式会社TOKOSのツキヤです!
今回は、Rust製の爆速LinterであるOxlintについて、ESLintからの移行方法をまとめていきます💪

前回のOxfmt移行記事の続編で、いよいよLinter編です。

Oxfmtへの移行方法【まだPrettier使ってるの?】

Rust製の爆速フォーマッターOxfmtへのPrettierからの移行方法を解説します。公式のClaude Skillでの一発移行、本リポジトリでの速度実測、VSCode(Cursor)での設定、Biomeとの比較まで詳しく紹介します。

実は以前のNext.js 15.5の記事で「LinterはBiomeよりもOxc(oxlint)に期待しています」と書いていたので、ようやくその伏線を回収できた形です😎

Linterについては、今までは基本的に皆さんESLintを使われていたかと思います。
しかし、LinterについてもOxlintの方が速度面で圧倒的なので、移行を検討されている方も多いのではないでしょうか。
また、型の認識についても最近安定版が出たのでいよいよ乗り換えない理由が無くなってきましたね。

本記事では以下の内容を紹介していきます💪

  • Oxlintの概要・特徴
  • TypeScript 7とOxlintの関係
  • 移行方法と本ブログでの実例
  • 型認識lintを含めた速度の実測
  • jsPluginsについて

対象読者

  • Oxlintへの移行を検討している方
  • ESLintの実行速度が気になっている方
  • TypeScript 7に上げたいが、typescript-eslintが対応しておらず困っている方

Oxlintの概要・特徴

概要

OxlintはOxcプロジェクトに含まれるRust製のLinterで、ESLintの代替を狙うツールです。
2025年6月に1.0がGAとなり、ShopifyやAirbnb、Mercedes-Benzなどの大規模プロジェクトでの採用実績があります✨

Oxlint

A collection of high-performance JavaScript tools written in Rust

oxc.rs

Airbnbでは126,000ファイル超の解析がCI上で7秒、Mercedes-BenzではESLintからの乗り換えでlint時間が71%削減されたと報告されています🔥

Announcing Oxlint 1.0

The first stable version of Oxlint, a fast & easy-to-use Rust-powered linter for JavaScript and TypeScript, is out. Learn about its 50~100x speed advantage over ESLint, support for 500+ rules, real-world adoption by major companies, and easy migration.

voidzero.dev

ESLintルールのカバレッジ

OxlintはESLintおよび主要プラグインのルールをRustで再実装しています。
組み込みで提供されている主なルールセットは下記です🙌

  • eslint本体
  • typescript-eslint
  • eslint-plugin-reacteslint-plugin-react-hooks
  • @next/eslint-plugin-next
  • eslint-plugin-unicorn

設定ファイルは.oxlintrc.jsonで、ESLintのJSON形式に近い書き味です。
後述の移行ツールを使えば、既存のeslint.config.mjsからほぼ自動で変換できます💪

ツキヤ
ツキヤ

Next.jsにもデフォルトで対応しているのは嬉しいですね😎

型認識lintがstableに

個人的に移行の決め手になったのが、型認識lint(type-aware linting)の対応です。
no-floating-promisesのような「型情報が無いと判定できないルール」は、長らくESLint(typescript-eslint)側でしか行なえませんでした。
しかし、Oxlintは2026年7月に型認識lintがstableになりました🎉

型認識ルールはtypescript-eslintの61個中59個が実装済みです。

GitHub - oxc-project/tsgolint: Type aware linting for oxlint

Type aware linting for oxlint. Contribute to oxc-project/tsgolint development by creating an account on GitHub.

github.com
ツキヤ
ツキヤ

「速いけど型認識ルールが無いから移行できない」が過去の話になりました✨

TypeScript 7とOxlintの関係

最近TypeScriptのバージョンが7に上がったので、そちらについても触れていきます。

TypeScript 7ではtypescript-eslintが動作しない

TypeScript 7はコンパイラ本体がGo製(通称tsgo)に置き換わった世代です。
爆速になった一方で、従来のJavaScript製コンパイラAPIが廃止されました(新APIは7.1で提供予定)。

Announcing TypeScript 7.0 - TypeScript

Today we are proud to announce the availability of TypeScript 7, a 10x faster native port of TypeScript! Since its early days, TypeScript has promised to

devblogs.microsoft.com

typescript-eslintはこのJavaScript APIを使って型情報を取得しているため、TypeScript 7では動きません。
実際、typescript-eslintのpeerDependenciesは>=4.8.4 <6.1.0です。
そのため、typescript@7とはインストール自体ができません😨

TypeScript 7対応のissueは存在するものの、ESLint側の制約もあり時間がかかりそうな状況です。

Enhancement: Use TS 7 (tsgo / typescript-go) for type information · Issue #10940 · typescript-eslint/typescript-eslint

Before You File a Proposal Please Confirm You Have Done The Following... I have searched for related issues and found none that match my proposal. I have searched the current rule list and found no...

github.com

登場人物の整理

このあたりは用語が似ていて混乱しやすいので、一度整理しておきます📝

名前正体
TypeScript 7Go製コンパイラが採用された新しいTypeScript本体
tsgoTypeScript 7のGo製コンパイラの通称
typescript-eslintESLint向けのTypeScriptプラグイン(型認識に従来のJS製コンパイラAPIを使う)
tsgolinttsgoをベースにしたOxc製の型認識lintエンジン
oxlint-tsgolinttsgolintをOxlintから使うためのnpmパッケージ

Oxlintの対応状況

Oxlintの型認識lint(oxlint-tsgolint)は、tsgoベースのバイナリを自前で同梱しており、プロジェクトにインストールされたTypeScriptパッケージを一切参照しません
実際、本ブログでもTypeScript 6のままOxlintへ移行し、型認識lintが動くことを確認してからTypeScript 7に上げています。

つまり、プロジェクトにインストールされているTypeScriptが5系・6系のままでも、型認識lintを利用できます。
typescript-eslintがTypeScript 7に対応するまで待つ」必要が、そもそも無くなるわけです😎

ただし1つ注意点があります。
同梱エンジンはTypeScript 7のセマンティクスで動作するため、ソースとtsconfigにはTypeScript 7互換性が必要です。
たとえばbaseUrlのようにTypeScript 7で廃止されたオプションを使っている場合は、先にtsconfig側の移行が必要です。

Type-Aware Linting | Oxlint

Linting with type information.

oxc.rs
ツキヤ
ツキヤ

LinterとTypeScriptのバージョンが完全に切り離されるのは嬉しくもありますが、上手いことバージョンを合わせて使っていく必要があるかもしれないですね🤔

移行方法

Oxlintへの移行方法は、Oxfmtの時と同様に大きく2通りあります。

方法A: Claude Skillを使う

oxc-projectが公式のClaude Skillmigrate-oxlintを公開しています。

ターミナル
npx skills add https://github.com/oxc-project/oxc --skill migrate-oxlint

スキル追加後にClaude Code等で/migrate-oxlintを実行すると、移行作業を対話的に進めてくれます。
使用感は前回のOxfmt移行記事で紹介したmigrate-oxfmtとほぼ同じなので、詳細はそちらをご覧ください🙌

oxc/.agents/skills/migrate-oxlint/SKILL.md at main · oxc-project/oxc

⚓ A collection of high-performance JavaScript tools. - oxc-project/oxc

github.com

方法B: @oxlint/migrateで移行する

公式の移行ツール@oxlint/migrateを使うと、既存のESLint設定から.oxlintrc.jsonを自動生成できます。

ターミナル
npx @oxlint/migrate eslint.config.mjs --type-aware --details

--type-awareを付けると型認識ルールを含めて変換され、--detailsで移行できなかったルールとその理由が一覧表示されます。
今回はこちらの方法で移行した実例を紹介していきます💪

GitHub - oxc-project/oxlint-migrate: Generates a .oxlintrc.json from an existing ESLint flat config.

Generates a .oxlintrc.json from an existing ESLint flat config. - oxc-project/oxlint-migrate

github.com

実際に移行してみた

本ブログ(TOKOS Tech Blog)のリポジトリで実際に移行した手順を紹介します。

移行前の構成

本ブログのESLint構成は、eslint.configs.allをベースにルールをてんこ盛りにした構成でした。
typescript-eslintstrictTypeCheckedstylisticTypeCheckedに加え、eslint-plugin-reactのall設定まで重ねています。
個別調整したルールは約90個あり、正直移行はやや大変かなと想像していました🥶

移行ツールの実行

@oxlint/migrateeslint.config.mjsを渡すと、359ルール中314ルール(約87%)が自動で.oxlintrc.jsonに変換されました✨

filesベースのoverrides(scripts/ディレクトリ専用の緩和設定)まで正しく変換されたのは驚きでした。

特に、Next.js固有のルールは@next/eslint-plugin-nextの21ルールすべてがOxlint側に存在し、完全に移行できていました🎉

自動変換後に手を入れたのは、主に下記の3点です。

  1. settings.react.versionの明示(Oxlintは"detect"非対応のため"19.2.8"を指定)
  2. oxlint-tsgolintのインストールと"typeAware": trueの確認
  3. package.jsonlintスクリプトをoxlint src scriptsに変更

"detect"は、eslint-plugin-reactがインストール済みのReactバージョンを自動検出してくれる設定値です。
Oxlintは"detect"に未対応のため、バージョンの明示が必要でした。

ターミナル
npm install -D oxlint oxlint-tsgolint

移行できなかったルールとその判断

一方で、移行できなかったルールもあります。
本ブログでどう判断したかも併せてまとめます📝

ルール状況本ブログでの判断
@typescript-eslint/naming-convention未実装(型情報必須のため後述のjsPluginsでも不可)コードレビューで担保する運用に切替
import/order実装しない方針(フォーマッターの責務と整理)OxfmtのsortImportsに引き継ぎ
@stylistic系の一部jsPlugins(alpha)経由でのみ利用可能alpha依存を避けて廃止 & Oxfmt側に移譲
react/jsx-no-leaked-render等の細則4件未実装影響が小さいため受容

import/orderについては、.oxfmtrc.jsonに下記を追加することでOxfmt側がimport文の並び替えを担当してくれます。

.oxfmtrc.json
{
  // その他設定...
  "sortImports": true,
}

lintルールとしての強制が無くなる分、CIにはoxfmt --checkを追加してフォーマット崩れを検知するようにしました💪

naming-conventionについては、昨今のLLMの賢さならよっぽどおかしな命名規則(ex: キャメルケースとスネークケースの混在)等は実装しないと思っています。
なので、コードレビューで担保する運用に切り替えました。

誤検知への対処

移行後の初回実行で、誤検知が1件だけありました。
JSXを返さない高階関数createCachedLoaderが、Reactコンポーネントと誤判定されてreact/function-component-definitionに引っかかるというものです。

こちらはESLintと同様の記法を使い、インラインで無効化できます。

cache.ts
const isDev = process.env.NODE_ENV === "development"
 
/**
 * ローダー関数をキャッシュ付きバージョンに変換する高階関数
 */
export const createCachedLoader = <T>(loader: () => T): (() => T) => {
  let cache: T | null = null
 
  // Reactコンポーネントではない高階関数の戻り値を誤検知するためoffに
  // oxlint-disable-next-line react/function-component-definition
  return () => {
    if (!isDev && cache !== null) {
      return cache
    }
    cache = loader()
    return cache
  }
}

約100ファイルの実プロジェクトを移行して誤検知がこの1件だけだったのは、正直期待以上でした✨

ツキヤ
ツキヤ

移行ツールの完成度が本当に高く、体感としてはOxfmt移行と同じくらいスムーズでした😎

移行後に実際にどれくらい速くなったのか

本ブログのリポジトリ(srcscriptsの約100ファイル)で実測してみました🔥
計測に使用したのはoxlint@1.79.0 + oxlint-tsgolint@7.0.2001で、各3回計測した中央値です。

ターミナル
time npx oxlint src scripts
eslintoxlintESLint比
型認識なし約6.7秒約0.36秒約19倍
型認識あり約6.7秒約1.1秒約6倍

型認識を有効にすると型認識なしの約3倍の時間がかかりますが、それでもESLint比では約6倍高速でした😎

「型認識lintは遅くなるから捨てる」という選択を取らずに済むのがOxlintの良さです。
no-floating-promisesのようなバグを未然に防ぐルールを維持したまま、lint時間を大幅に短縮できます💪

ツキヤ
ツキヤ

CIのlintジョブも体感でかなり速くなりました。地味にPRのマージ待ち時間に効いてきます✨

TypeScript 7に上げてみた

本記事のメインテーマではありませんが、Oxlint移行によってtypescript-eslintへの依存が消えたので、TypeScript 7に上げてみました。
結論、typescriptのバージョンを上げるだけで完了でした🎉

ターミナル
npm install -D typescript@^7.0.2

TypeScript 7ではtypesのデフォルトが[]になる等の破壊的変更があります。
ただ、Next.jsプロジェクトではnext-env.d.ts経由の型参照で吸収されるため、本ブログではtsconfigとコードを一切変更せずに済みました。
tsc --noEmitもエラーゼロで通っています✨
Next.js 16.3はTypeScript 7を公式サポートしており、next buildはプロジェクトローカルのtscコマンドを使って型チェックしてくれます🙌

Next.js 16.3

Next.js 16.3 introduces Instant Navigations, a suite of tools for single-page-app responsiveness, plus a faster dev server, faster builds, and improved tooling for AI agents.

nextjs.org

TypeScript&#32;7&#32;-&#32;Visual&#32;Studio&#32;Marketplace

Extension&#32;for&#32;Visual&#32;Studio&#32;Code&#32;-&#32;TypeScript&#32;and&#32;JavaScript&#32;language&#32;support&#32;powered&#32;by&#32;the&#32;native&#32;TypeScript&#32;language&#32;server.

marketplace.visualstudio.com
ツキヤ
ツキヤ

「Linterが理由でTypeScriptを上げられない」状態から解放されたのが嬉しかったです🥳

jsPlugins(alpha)について

「組み込みルールに無いプラグインはどうするの?」という疑問については、jsPluginsで解決可能です!
OxlintはESLint v9互換のプラグインAPIをJavaScriptで提供しており、既存のESLintプラグインをそのまま読み込める仕組みを開発中です。

設定は.oxlintrc.jsonjsPluginsにプラグインを追加し、rulesで使いたいルールを指定します。
組み込みプラグインと名前が衝突する場合は、下記のようにエイリアスも指定できます。

.oxlintrc.json
{
  "jsPlugins": [
    // 組み込みに無いプラグインはそのまま指定
    "@stylistic/eslint-plugin",
    // 組み込みの`jsdoc`と名前が衝突するためエイリアスを付ける
    {
      "name": "jsdoc-js", // ルール名のプレフィックス
      "specifier": "eslint-plugin-jsdoc", // 実際のnpmパッケージ名
    },
  ],
  // 使いたいルールを指定する
  "rules": {
    "@stylistic/semi": ["error", "never"],
    "jsdoc-js/check-alignment": "error", // プレフィックスはエイリアス名
  },
}

ほぼ全てのパターンにおいて、eslint-plugin-react-hooks等の実プラグインで正常に動作することが確認されています。
ただし、下記の制約があります。

  • 型情報を必要とするルールは動かない
  • カスタムパーサ(Vue/Svelte等)は非対応
  • alpha段階のため、APIは今後変わる可能性がある

本ブログの移行では@stylisticの2ルールをjsPluginsに載せる選択肢もありましたが、alpha段階の機構に依存するのを避けて廃止を選びました。(+ oxfmt側のルールに寄せたかった)
安定化したらあらためて活用を検討したいところです💪

JS Plugins | Oxlint

A collection of high-performance JavaScript tools written in Rust

oxc.rs

VSCode(Cursor)での設定

エディタ統合は、Oxfmt移行時にインストールした公式拡張機能Oxcがそのまま使えます。
拡張機能が.oxlintrc.jsonを読み取り、エディタ上でリアルタイムにlint結果を表示してくれます🙌

拡張機能のインストール方法やsettings.jsonの設定は、前回の記事をご覧ください。

Oxfmtへの移行方法【まだPrettier使ってるの?】

Rust製の爆速フォーマッターOxfmtへのPrettierからの移行方法を解説します。公式のClaude Skillでの一発移行、本リポジトリでの速度実測、VSCode(Cursor)での設定、Biomeとの比較まで詳しく紹介します。

補足

最後に、移行のトレードオフ及び本ブログでの方針を記載します。

  • naming-conventionによる命名規則の機械強制(→ レビュー運用でカバー)
  • import/orderのlintとしての強制(→ OxfmtのsortImports + oxfmt --checkでカバー)
  • @stylistic系の体裁ルールの一部(→ フォーマッターとレビューでカバー)
  • ESLintの豊富なサードパーティプラグイン資産(→ jsPluginsの安定化待ち)

本ブログでは、これらを許容しても「TypeScript 7へアップデート」「速度6倍」の方を取った形です。
逆に言うと、naming-conventionやサードパーティプラグインを必須とするプロジェクトでは、もうしばらくESLint併用(eslint-plugin-oxlintでルール重複を回避する構成)が現実的だと思います🤔

とは言え、今後の潮流としてはOxlintの方が良さそうなので、今後はOxlintをメインに使っていきたいと思います。
プラス、他のプロジェクトもoxlint+oxfmtで運用していて問題を感じていないので、やはり移行を推奨という感想になりました💪

おわりに

今回は、Rust製の爆速LinterであるOxlintへの移行方法を本ブログでの実例と実測値を交えて紹介しました🎉

  • 型認識lintを維持したまま約6倍高速化(型認識なしなら約19倍)
  • @oxlint/migrateで約87%のルールが自動移行、Next.jsルールは21/21で完全移行
  • 型認識lintがインストール済みTypeScriptに依存しなくなり、TypeScript 7へ即移行可能に
  • 移行しきれないルール(naming-convention等)はあるが、大きな問題は無い

OxfmtとOxlintが揃い、本ブログのフォーマッター・LinterはOxcスタックに完全移行しました🎉
これからもアップデート等があれば、随時記事にしていきたいと思います!

The JavaScript Oxidation Compiler

A collection of high-performance JavaScript tools written in Rust

oxc.rs

この記事を書いた人

西原月熙
西原月熙

TOKOSのテックリード。上流工程からコーディング、インフラ系まで色々やっている器用貧乏です。最近は特にフロントエンドのキャッチアップに力を入れています💪 好きな音楽はボーカロイドです🤖