← ブログ一覧

BiomeでESLintとお別れできる?

RustベースのBiome v2.0がESLint・Prettierを置き換えられるか徹底検証。速度差・機能比較・移行手順・ESLintプラグイン資産との共存パターンまで会話形式でわかりやすく解説。


この記事の結論: Biome v2.0はフォーマッターとしてはPrettierをほぼ完全互換で即置き換えられるが、eslint-plugin-react-hooks等のプラグイン資産があるならLintはESLintと共存させる「段階移行」が現実解。その具体的な設定とCIコマンドまで載せた。

リナ社長(高校生社長のやり手ギャル)× タクヤ(入社3年目)— 今回は、CIのlintが遅い問題をきっかけに、Rust製ツールBiomeへの乗り換えをどこまで進めていいか整理した回。(登場人物について


リナ社長「ねえタクヤ、ちょっと聞いてもいい?うちのCI、lint走るたびに30秒くらいかかってるじゃん。えぐくない?」

タクヤ「あー、確かに。ESLintとPrettierを両方走らせてるので、プロジェクトが大きくなるにつれてじわじわ遅くなってますよね……」

リナ社長「そこでさ、最近めっちゃ気になってるのが『Biome』なんだよね。Rustで書かれてて爆速らしいし。ESLintとPrettierを1個で置き換えられるって話で」

タクヤ「気になってます!でも本当に全部置き換えられるんですか?既存のESLintプラグインとかも?」

リナ社長「そこが肝なんだよね。今日はそれ一緒に整理してこ!」


「ESLintとPrettier、なんか重くない?」——Rustツールチェーンが台頭したワケ

リナ社長「まず背景からいくね。ESLintもPrettierも、もともとJavaScriptで書かれてるじゃん。Node.jsで動くから、起動コストとか解析コストがどうしても高くなるんだよね」

タクヤ「確かに、ファイル数が増えてくると体感でわかるくらい遅くなりますよね」

リナ社長「そこに登場したのがRustベースのツール群。SWCはBabelの代替として2020年ごろから注目されて、Biomeはそこから派生する形で生まれてきたんだよ。元々は『Rome』っていうプロジェクトで、それがforkされてBiomeになった感じ」

RustはネイティブバイナリにコンパイルされるからNode.jsのオーバーヘッドがないし、マルチスレッドで並列処理もしやすい。ESLintと比べて10〜50倍高速と言われていて、大規模プロジェクトほど差が出る。

タクヤ「10〜50倍は相当ですね……!それはCI時間に如実に出そうです」

リナ社長「でしょ?うちみたいにCIコスト気にしてる会社にはえぐい魅力なんだよ」


BiomeはESLintの何を置き換えるの?できることとできないことを整理

タクヤ「ところでBiome v2.0って、具体的にどこまでESLint・Prettierの機能をカバーしてるんですか?」

リナ社長「いい質問!整理してみたよ」

機能ESLint + PrettierBiome v2.0
JavaScriptのLint
TypeScriptのLint✅(@typescript-eslint✅(組み込み)
JSX/TSXのLint
コードフォーマット✅(Prettier)
Import順の整理✅(プラグイン)✅(v2.0で強化)
設定ファイル.eslintrc + .prettierrc など複数biome.json 1本
カスタムルール(JS製)❌(未対応)
CSS/SCSSのLint✅(Stylelintなど別途)✅(実験的サポート)
GraphQLのLint✅(プラグイン)✅(v2.0で追加)

タクヤ「設定ファイルが1本で済むのは地味にありがたいですね!でも『カスタムルール(JS製)』が❌なのは気になります」

リナ社長「そこが一番の注意ポイントだね。ESLintのカスタムルールはJavaScript/TypeScriptで書けるじゃん。Biomeはそれが今のところできない。プラグインエコシステムもまだ発展途上だから、ESLintに依存してるルールがあると困ることがある」

タクヤeslint-plugin-react-hooks とか、プロジェクトで使いまくってますよね……」

リナ社長「そうそう。そこはまだBiomeじゃカバーできないんだよね。後で『共存パターン』として話すね」


実際に移行するとどうなる?設定・コマンド・CIの変化を実演

タクヤ「じゃあ実際に試してみたいんですが、最初何をすればいいですか?」

リナ社長「まずインストールから!」

npm install --save-dev @biomejs/biome

続いて、設定ファイルを初期化する。

npx @biomejs/biome init

これで biome.json が生成される。最小構成はこんな感じ。

{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 80
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",
      "trailingCommas": "all"
    }
  }
}

タクヤ「あ、これだけで動くんですか?」

リナ社長「そう!シンプルでしょ。で、チェックはこのコマンド1発」

npx @biomejs/biome check .

lintとformatチェックを同時にやってくれる。自動修正したいときはこう。

npx @biomejs/biome check --write .

タクヤ--write でフォーマットも自動修正されるんですね。PrettierとESLintの --fix が1コマンドで済む感じか」

リナ社長「そういうこと!CIもめちゃシンプルになるんだよ。GitHub Actionsならこんな感じ」

- name: Lint & Format Check
  run: npx @biomejs/biome ci .

biome ci はCIモード専用で、write操作なしで差分があればエラー終了してくれる。

タクヤbiome cibiome check を使い分けるんですね。CI用コマンドが別に用意されてるのはわかりやすいです」

リナ社長「VSCode拡張もあるから入れとくといいよ。保存時に自動フォーマットもできるし、エディタ上でlintエラーがリアルタイムで出る」


まだ乗り換えなくていいケースもある——ESLintプラグイン資産との折り合い

タクヤ「じゃあ今すぐ全部BiomeにしたらOKですか?」

リナ社長「うーん、それはちょっと待って。冷静に整理するね」

既存プロジェクトで以下のESLintプラグインを使っているなら、まだBiomeだけでは代替できないケースがある。

  • eslint-plugin-react-hooks(ReactのHooksルール)
  • eslint-plugin-import(import解決の細かい制御)
  • @typescript-eslint の型情報を使う高度なルール(型チェック系)
  • プロジェクト固有のカスタムルール

タクヤ「うちはreact-hooksプラグイン使ってますし、型情報を使ったESLintルールも一部入ってますね……」

リナ社長「だよね。そういうケースは『全置き換えじゃなくて段階移行』でいいんだよ」

具体的には、Prettierだけ先にBiomeに置き換える。フォーマッターとしてのBiomeはほぼPrettierの完全互換で、設定もシンプルだ。

{
  "formatter": {
    "enabled": true
  },
  "linter": {
    "enabled": false
  }
}

こうしてフォーマットだけBiomeに任せて、LintはESLintのままにする。CIでは両方走らせてもいいし、段階的にESLintのルールをBiomeに移行していくのが現実的だ。

タクヤ「共存できるんですね!それなら試しやすいです」

リナ社長「Biome v2.0でGraphQLサポートとかimport整理が強化されたから、今後もどんどんカバレッジ広がるはずだよ。React Hooksルールも、コミュニティからの要望が多くてロードマップに入ってるし」

タクヤ「じゃあ今うちのプロジェクトで、とりあえずPrettierをBiomeに置き換えるところから始めてみますか?」

リナ社長「それがベストじゃん!速度の恩恵はすぐ感じられるし、リスクも低い。まず小さく始めて、Biomeのカバレッジが広がるにつれて少しずつESLintを減らしていく。それが現実的な乗り換えルートだよ。焦って全部切り替えるより、段階移行でリスクなく速くなれるならそっちの方がえぐくない?」


参考

コメント