Skip to content

✍️ 필사 모드: 2026年のフォーマッタとリンタ — Biome、dprint、Ruff、oxc、Prettier 4、ESLint v9の実情

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

プロローグ — なぜまたフォーマッタ・リンタの話か

prettier --write . の一行で完結する時代があった。2020年頃の話だ。それから5年経つうちに、同じコマンドはモノレポで30秒、CIで2分まで膨らんだ。eslint --max-warnings 0 はさらに遅く、ある時点で「pre-commitフックからlintを外すべきか」を真剣に議論していた。

同じ時期、Python陣営にも似た痛みがあった。black + flake8 + isort + pylint の4段コンボは安定していたが遅い。大きなリポジトリで一度走らせるのに分単位かかり、4つのツールの設定ファイルがバラバラに動いた。

そこにRust陣営のツール作者が違う答えを持ってきた。速度が本当に100倍速ければ、他のすべてが変わるという答えだ。Ruff(2022)がPythonで証明し、Biome(旧Rome)がJS/TSで同じ道を歩んだ。dprint、oxc、ty(型チェッカ)、uv(パッケージマネージャ)まで — AstralとBiomeチーム、Boshen(oxc)のような小さなチームが牽引するRust再実装の波である。

2026年現在、Prettier 4はRustプラグインの道を公式に取り入れ、ESLint v9のflat configは安定し、typescript-eslint v8は単一パッケージに統合された。Biome 2はmulti-file解析とimport sortingを正式機能として備え、Ruffは実質的にPythonリンティングのデフォルトとなった。

本稿はその地形を整理する。どのツールがどこで何が得意なのか、「Rustで書き直せばすべて良くなる」という命題はどこまで真なのか、そして自分のチームには何が合うのか。マーケティングではなく、測定可能なトレードオフで。

核心の一行:ツールは速くなり統合された。だが「Biome一行ですべて解決」という単純な絵はまだ成立していない。どのトレードオフを受け入れるかが選択を決める。


1章 · 地形図 — 2026年のフォーマッタ・リンタ全体像

まず大きな絵を描く。言語ごとにどんな選択肢があり、誰がどこで活躍しているか。

言語 / 領域伝統的なツール2026年の主力次世代の候補
JS / TSPrettier + ESLintPrettier + ESLint v9、Biome 2oxc、dprint
Pythonblack + flake8 + isort + pylintRuff(format + lint)ty(型チェッカ)
Rustrustfmt + clippyrustfmt + clippy— (既にRust)
Gogofmt + golangci-lint同じ
CSS / SCSSPrettier + stylelintPrettier + stylelint、Biome 2dprint、oxc
MarkdownPrettier、remark-lintPrettier、dprint
TOML / YAML / JSONPrettierdprint、taplo、yamlfmt
多言語モノレポPrettier + ESLintdprint(統合フォーマッタ)、Biome

カテゴリ別の一行まとめ

  • フォーマッタ:コードの見た目(空白・改行・引用符・セミコロン)を決める。意見を持ち強制する。Prettier、Biome format、dprint、rustfmt、gofmt、Ruff format、blackがここに属する
  • リンタ:意味的な問題(未使用変数、潜在的バグ、アンチパターン)を検出する。ESLint、Biome lint、Ruff lint、clippy、golangci-lint、stylelint、pylint
  • 型チェッカ:型エラーを検出する。tsc、mypy、pyright、ty(Astral)、Flow
  • フォーマッタ・リンタ統合ツール:単一バイナリで両方やる新世代。BiomeとRuffが代表

本稿の主役は3番目の流れ — Rustで書かれた次世代統合ツールたち。既存ツールを置き換える場所、補完する場所、まだ届かない場所を見る。

一行まとめ:言語ごとに事情が違う。Pythonは実質Ruffが正解、JS/TSはまだBiome vs Prettier+ESLintの決断が残り、モノレポではdprintが新しい選択肢として加わった。


2章 · Rust再実装のパターン — なぜ10〜100倍速いのか

まず「なぜ速いのか」を押さえる。マーケティングではなく構造の違いだ。

測定可能な速度差

Biome公式ドキュメントが示す数字 — 単一ファイルのフォーマットでBiomeはPrettierの25〜35倍速く、大きなリポジトリではさらに差が開く。Ruffは同じルールでflake8と比べて約100倍速いという報告が頻繁にある(中〜大規模Pythonリポジトリで分単位が秒単位に)。

実際の使用報告でよく見る数字:

  • Prettierのモノレポフォーマット30秒 → Biome 1〜2秒
  • flake8 + black のモノレポ点検90秒 → Ruff 2〜3秒
  • ESLint flat configのモノレポlint 45秒 → Biome 3〜5秒(ルールカバレッジは違う、後述)
  • Prettierの単一ファイルフォーマット 300ms → dprint/Biome 5〜15ms

なぜここまで差がつくのか

  1. 言語自体の差 — JSツールはV8 JIT上で動くインタプリタコード、Rustツールはネイティブバイナリ。これだけで3〜10倍
  2. 単一パスの解析 — 従来ツールはlex→parse→AST変換を複数回行う。Biome/oxc/Ruffは一度のパスでlossless concrete syntax tree(CST)を作り、すべての解析で再利用
  3. 並列化 — Rustのデータ並列性を活かしてファイルを真に並列で処理。JSツールはシングルスレッドで、Workerプールを使ってもシリアライズ費用がかかる
  4. メモリレイアウト — CSTノードをcache-friendlyな配列に格納(rowan、oxc-resolverといったライブラリ)。アロケーションが少ない
  5. 再起動コスト — Rustバイナリは起動が1〜5ms、Nodeは50〜200ms。CLI反復呼び出しで大差

速さの二次効果

  • pre-commitフックで再び実行可能になる — 30秒だったものが1秒になれば、フックに戻しても問題ない
  • エディタ統合がライブになる — 入力するたびにlintが可能
  • CIで別途キャッシュする必要が減る — どうせ速いのだから
  • モノレポ全体のlintが日常になる — 分単位ならCIだけ、秒単位ならローカルでも

一行まとめ:速さそのものより、速さが可能にするワークフロー変化が本質だ。「どうせ遅いから無理」という制約が外れる。


3章 · Biome 2 — フォーマッタ・リンタ統合の先頭

Biomeは最も野心的な統合ツールだ。元の名前はRome(2020年、Sebastian McKenzie — Babelの作者)、資金不足で停止、2023年にコミュニティフォークとしてBiomeが出発し、2024年にBiome 1.0、2025年にBiome 2.0。

Biome 2の核心的な約束

  • JS / TS / JSX / TSX / JSON / CSS / GraphQLのフォーマット + リントを単一バイナリで
  • 単一の設定ファイル biome.json — Prettier+ESLintの2つを統合
  • 型認識リンタ — typescript-eslintと似たtype-awareルールの一部(V2でmulti-file解析を追加)
  • import並べ替え — eslint-plugin-importの一部を代替
  • diff format — 変更部分のみフォーマット可能(CIで大きなPRに有用)
  • マイグレーションツール biome migrate prettierbiome migrate eslint

設定例

{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
  "files": { "ignoreUnknown": true },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": { "quoteStyle": "single", "semicolons": "asNeeded" }
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" },
      "style": { "useImportType": "warn" },
      "suspicious": { "noExplicitAny": "warn" }
    }
  },
  "assist": {
    "enabled": true,
    "actions": { "source": { "organizeImports": "on" } }
  }
}

Biomeが得意な場面

  • JS/TS中心、シンプルなルールセット — 90%のルールカバレッジで十分なチーム
  • 単一設定の価値を理解するチーム — Prettier+ESLint設定の複雑さに疲れたチーム
  • CI速度が真の問題のチーム — モノレポlintが分単位かかる場合
  • ローカルIDE統合速度 — VS Code拡張が即座に反応

Biomeがまだ届かない場所

  • ESLintプラグインエコシステムの不在 — eslint-plugin-react-hooks、eslint-plugin-jest、eslint-plugin-tailwindcss、eslint-plugin-importといった外部ルールを直接使えない。Biomeが一部を内蔵に吸収中だが、ESLintプラグインの1:1代替は難しい
  • Vue、Svelteなど非標準ファイル形式の未対応.vue.svelte はまだ(コミュニティプラグインの一部はあるが公式未対応)
  • Markdown / YAML / TOMLフォーマット未対応 — Prettierがカバーしていた領域ができない
  • 型認識リンタの限界 — typescript-eslintの全ルールセットには追いついていない
  • マイグレーション費用 — 大きなリポジトリでESLintルール差を手で埋めるのに数日

判断基準

チームの状況Biomeの適合度
新規JS/TSプロジェクト、シンプルなルール非常に高い
モノレポ、CI速度重要、Vue/Svelteなし高い
既存のPrettier+ESLint、満足中移行する動機が弱い
eslint-plugin-* を深く活用まだ難しい
Vue / Svelte / Astro / MDXの比重大推奨しない

一行まとめ:Biomeは「JS/TSだけ見れば」最も魅力的な統合ツールだ。ただしプラグインエコシステムと非標準ファイル対応で、Prettier+ESLintを完全に置き換えるにはまだ空白がある。


4章 · dprint — プラグインベースの多言語フォーマッタ

dprintは別のアプローチを取る。コア自体は小さく言語ごとのプラグインで拡張する。単一ツールでJS/TS、JSON、Markdown、TOML、Dockerfile、SQLを一度にフォーマット。

dprintの差別点

  • WASMプラグインシステム — 言語サポートはプラグイン。コアは速くて小さい
  • 多言語モノレポに最適 — Prettierが対応しないTOML、Dockerfileまで一つのツールで
  • Rust実装 + Rust/WASMプラグインSDK
  • 純粋なフォーマッタ — リンティングはしない。一つのことだけを上手くやる

設定例

{
  "lineWidth": 100,
  "indentWidth": 2,
  "useTabs": false,
  "typescript": {
    "quoteStyle": "preferSingle",
    "semiColons": "asi"
  },
  "json": {
    "lineWidth": 200
  },
  "markdown": {
    "textWrap": "always"
  },
  "toml": {},
  "dockerfile": {},
  "plugins": [
    "https://plugins.dprint.dev/typescript-0.93.0.wasm",
    "https://plugins.dprint.dev/json-0.20.0.wasm",
    "https://plugins.dprint.dev/markdown-0.18.0.wasm",
    "https://plugins.dprint.dev/toml-0.7.1.wasm",
    "https://plugins.dprint.dev/dockerfile-0.3.4.wasm"
  ],
  "includes": ["**/*.{ts,tsx,js,jsx,json,md,toml,Dockerfile}"],
  "excludes": ["**/node_modules", "**/dist"]
}

dprintが得意な場面

  • 多言語モノレポ — TS + JSON + Markdown + TOML + Dockerfile を一つのツールで
  • 純粋なフォーマット価値 — リンティングまで統合しなくていい、ただ速いPrettier代替
  • プラグイン分離 — 各言語がWASMモジュールで分離され依存関係衝突なし
  • バージョン固定の利便性dprint config update でプラグインバージョンを一括更新

dprintが届かない場所

  • リンタなし — リンタは別途(ESLint、Biome lint、Ruffなど)
  • JS/TSルールカバレッジ — Prettierよりやや少ない。オプションの意見が強い
  • エディタ統合の成熟度 — VS Code拡張はあるが、Prettierほど滑らかではない
  • CSS / GraphQLプラグインの状態 — 一部プラグインはベータまたはコミュニティメンテナンス

誰が使うか

  • Deno標準コードベース(dprint自体がDenoフレンドリー)
  • インフラリポジトリ(IaC、Docker、K8s、Terraformと相性が良い)
  • 多言語モノレポ(TS + Python + インフラコードが共存する場所)

一行まとめ:dprintは「一つのツールですべてのテキストフォーマット」を狙う。リンティングなしフォーマットのみ、多言語が本当に混在するモノレポで輝く。


5章 · Ruff — Pythonを制圧したRustツール

Ruffは最も圧倒的な成功事例だ。Charlie Marsh(Astral)が2022年に初リリースし、2026年現在PyPIのPythonツールダウンロード統計で実質1位。Django、Pandas、FastAPI、Pydantic、Apache Airflow、scikit-learnといったメジャープロジェクトがRuffを採用した。

Ruffの約束

  • flake8 + isort + pydocstyle + pyupgrade + bandit + autoflake + blackの代替 — 7〜10個のツールを1つに
  • 800以上のリントルール — flake8 + 主要プラグインルールのほとんどを移植
  • フォーマッタ内蔵ruff format はblack互換(blackの強い意見をほぼそのまま継承)
  • import並べ替え — isortの代替
  • 自動修正ruff check --fix で安全な修正を自動化
  • 単一設定pyproject.toml[tool.ruff] セクション一つに

設定例

[tool.ruff]
line-length = 100
target-version = "py312"
extend-exclude = ["migrations", ".venv", "build"]

[tool.ruff.lint]
select = [
  "E", "W",      # pycodestyle
  "F",           # pyflakes
  "I",           # isort
  "N",           # pep8-naming
  "UP",          # pyupgrade
  "B",           # flake8-bugbear
  "C4",          # flake8-comprehensions
  "DTZ",         # flake8-datetimez
  "S",           # flake8-bandit (security)
  "RUF",         # ruff-specific
]
ignore = ["E501"]  # line-too-long handled by formatter
fixable = ["ALL"]
unfixable = []

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"]  # allow assert in tests
"__init__.py" = ["F401"]  # allow unused imports

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = true

Ruffが得意な場面 — ほぼすべて

  • 速度 — flake8+pylint 90秒 → Ruff 2秒
  • 単一ツール — pre-commit設定が7行から1行に
  • 自動修正の範囲 — flake8が報告だけしていたものをRuffは修正
  • CIキャッシュ不要 — どうせ速い
  • flake8ルールセレクタ互換 — マイグレーション費用が低い

Ruffの限界 / 違い

  • mypyの代替ではない — 型チェックは別途。Astralが ty (型チェッカ、Rust)を開発中だが2026年現在アルファ/ベータ段階
  • blackと100%同じではない — 95%は同じだがエッジケース(長い文字列、複雑な式)で一部違う。一度 ruff format を走らせるとdiffが発生し得る — 大規模PRが一度必要
  • pylintの深い解析の一部が不十分too-many-locals、cyclomatic complexity のようなルールは制限的
  • プラグインシステムなし — すべてのルールがコアに内蔵。カスタムルール追加が難しい

Astralの大きな絵 — Rust再実装スタック全体

Charlie Marshの野心はRuffに留まらない。AstralはPythonツールチェイン全体をRustで書き直している。

ツール代替対象状態(2026)
Ruffflake8、isort、black、pydocstyle、...安定、広範囲採用
uvpip、virtualenv、pip-tools、pipx、poetry(一部)安定、急速拡散
tymypy、pyright(部分)アルファ/ベータ
ryepoetry、hatch(概念的)uvに吸収中

全体パターン:「ツール一つが速ければそのツール中心にすべてのワークフローが再編成される」。同じパターンがBiome(JS)、oxc(JS)で繰り返される。

一行まとめ:RuffはPythonツールチェインで実質デフォルトになった。理由はシンプル — 速く、統合されており、マイグレーション費用が低い。


6章 · oxc — Rust JavaScriptツールチェインファミリ

oxcは別の野心だ。Boshenが率いるプロジェクトで、JavaScriptツールチェイン全体をRustで作る。パーサ、リゾルバ、トランスフォーマ、リンタ、フォーマッタ、ミニファイア。Biomeが「単一ユーザツール」なら、oxcは「他のツールが使うコンポーネントライブラリ」に近い。

oxcの構成要素

コンポーネント役割比較対象
oxc-parserJS/TSパーサacorn、esprima、swcパーサ
oxc-resolverモジュール解決enhanced-resolve
oxc-transformerJS/TS変換Babel、swc
oxlintリンタESLint
oxc-prettierフォーマッタ(Prettier Rustポート)Prettier
oxc-minifierミニファイアterser、swc、esbuild

oxlint — ESLintを狙うRustリンタ

oxlintはESLintコアルールとプラグイン一部をRustで再実装。2026年現在、oxlintはESLint v9互換モードを一部サポートしており、高速な事前チェック(pre-flight check)用途で推奨される。

# 速いlint(oxlint)、深いlint(ESLint)
oxlint --deny-warnings src/
# ESLint互換レポート
oxlint --rules-include=react-hooks src/

oxcが得意な場面

  • ビルドツール作者 / フレームワーク作者 — Rspack、Rolldownといったツールがoxcを内部採用。速いコンポーネントライブラリ
  • 事前チェックlint — Lefthook/Huskyのpre-commitフックでESLint全体の代わりにoxlintで70%のルールを0.5秒で点検
  • CI第一段階 — 速く失敗。oxlint通過後にESLint深い点検
  • Prettier互換フォーマッタ — Prettier 4のRustプラグインパスの一翼

oxcの限界

  • プラグインシステム未成熟 — ESLintプラグインを直接使えない
  • リントルールカバレッジが部分的 — ESLintの全ルール1:1マッピングはまだ
  • 単独ツールとして使いにくい — Biomeのように「これだけ使えば終わり」ではなく補完材
  • フォーマッタはPrettier 4統合パスにより近い — 単独使用例は少ない

Biome vs oxc — 何が違うか

比較Biomeoxc
目標統合ユーザツールコンポーネントライブラリ + ツールファミリ
単一設定あり(biome.json)ツールごとに別
ユーザ体験「Prettier+ESLintの代替」「ESLintを速く補完」
プラグイン内蔵中心(計画)WASMプラグイン
誰が採用アプリケーションチームビルドツール作者、フレームワーク

一行まとめ:Biomeがユーザツール、oxcはコンポーネントファミリ。ユーザの立場からはBiomeが直感的、ツール作者の立場からはoxcが有用。この二つは競合ではなく異なるレイヤーで働く。


7章 · Prettier 4 — 帝王はどう応答したか

Prettierは2017年以降、事実上JS/TSフォーマッタのデフォルトだった。意見を持って強制し、設定がほぼないことが核心の哲学。結果、ほぼすべてのプロジェクトが採用。

しかし速度の問題が累積した。Prettier 3まではピュアJS、Node上で動くツール。速いツールとの差が広がるにつれ、Prettierチームは2025年からRustプラグインパスを公式化した。

Prettier 4の核心的変化

  • Rustベースのパーサ・フォーマッタパス — JS/TSコアはoxcまたはswcベースのRustバックエンドを採用できるアダプタを追加
  • 互換性優先 — Prettier 3の出力とビット単位一致が目標(95%+ 一致)。100%への道は段階的
  • プラグインAPI安定化 — Markdown、YAML、GraphQL、Tailwindといったプラグインはそのまま
  • 速度改善 — Rustバックエンド有効時に5〜15倍高速化(Biomeほどではないが意味がある)
  • 単一インストールモデル維持npm install prettier 一行で終わるユーザ体験は維持

設定例(Prettier 4)

{
  "experimentalRustBackend": true,
  "printWidth": 100,
  "singleQuote": true,
  "semi": false,
  "trailingComma": "all",
  "plugins": [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-organize-imports"
  ]
}

Prettierが生き残る理由

  • エコシステムの慣性 — Tailwind並べ替え、import並べ替え、Astro/Svelte/Vueプラグインなど数百のプラグイン
  • エディタ統合の完成度 — VS Codeの「format on save」が最も安定
  • 意見の意見 — Prettierスタイルが標準になった状態 — BiomeもPrettier互換出力を約束するほど
  • 豊富なファイル形式サポート — JSON、YAML、Markdown、GraphQL、MDXなどPrettierが最も広い

Prettier vs Biome — 2026年の決断

基準Prettier 4Biome 2
JS/TSフォーマット速度5〜15倍高速化(Rustバックエンド)25〜35倍高速化
リンタ統合なし(ESLint別途)統合
プラグインエコシステム巨大小さい
非標準ファイルサポート広い狭い
単一設定部分(依然として.prettierrc + .eslintrc)完全(biome.json)
マイグレーション費用なし(既に使用中)中程度(biome migrate)

一行まとめ:Prettierは死なない — エコシステムが深すぎる。Rustバックエンドで速度差を縮め、ESLintとの組み合わせで生き残る。Biomeは「統合の価値」が大きい新規プロジェクトで強い。


8章 · ESLint v9とtypescript-eslint v8 — flat config時代

ESLint陣営も止まらなかった。

ESLint v9の変化

  • flat configの標準化.eslintrc.* (legacy)の代わりに eslint.config.js (または .ts )がデフォルト。v10でlegacyは削除予定
  • TypeScript ESMファースト — flat configがESMに自然
  • --inspect-config — どのルールがどこでなぜ有効になったか可視化
  • CLI安定化eslint . がデフォルト動作(v9から引数なしでも動作)
  • deprecatedルール整理 — formatting関連ルールはすべてdeprecated(Prettierに委譲)

flat config例

// eslint.config.js
import js from '@eslint/js'
import tseslint from 'typescript-eslint'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default tseslint.config(
  { ignores: ['dist', 'build', '.next'] },
  js.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    files: ['**/*.{ts,tsx}'],
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    plugins: {
      'react-hooks': reactHooks,
      'react-refresh': reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      'react-refresh/only-export-components': 'warn',
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
    },
  }
)

typescript-eslint v8 — 単一パッケージ

v7以前は @typescript-eslint/parser@typescript-eslint/eslint-plugin を別々にインストールする必要があった。v8では typescript-eslint 単一パッケージに統合。設定もより短くなった。

npm i -D typescript-eslint

projectService機能 — 型認識lintの費用削減

型認識lint(@typescript-eslint/recommended-type-checked)は正確だが遅かった。v8の projectService はTypeScript LSPのように動作する — tsconfigを自動発見し、ファイル単位で型情報をlazyにロード。モノレポでlint速度を2〜5倍改善。

ESLintが生き残る理由

  • プラグインエコシステム — eslint-plugin-react-hooks、eslint-plugin-jest、eslint-plugin-jsx-a11y、eslint-plugin-import、eslint-plugin-tailwindcss、eslint-plugin-storybookなど数百
  • 型認識ルールの深さno-floating-promisesawait-thenableno-misused-promises のように型チェッカなしでは捉えられないルール
  • ユーザ定義ルールの容易さ — JSで書いたプラグインを簡単に追加
  • レガシー互換 — flat configへ移行しても旧プラグインのほとんどを受容

ESLintとBiomeの共存パターン

多くのチームがこうしている:

フォーマット:  Prettier (または Biome format)
速いリント: oxlint / Biome lint (pre-commit、即時フィードバック)
深いリント: ESLint (CI、型認識 + プラグイン)

ESLintを捨てるのではなく「速い1次通過 + 深い2次通過」に分離。Biome+ESLintが一緒に動くのは奇妙に見えるが実際にはうまく機能する。

一行まとめ:ESLintはv9 flat configで整理され、typescript-eslint v8のprojectServiceで速度も改善された。プラグインエコシステムのおかげで近い将来死なない。


9章 · stylelintとCSSツール

CSS陣営も似た流れだ。

stylelint v16

  • 依然としてCSS / SCSS / Lessリンティングのデフォルト
  • v16でflat-configに似た単純化
  • Biome 2のCSS lintが一部ルールを吸収中だがstylelintの全体カバレッジには及ばない
  • Tailwind / CSS Modules / postcss統合は依然stylelintが強い

CSSフォーマット — 誰が得意か

ツールCSSSCSSLessTailwindクラス並べ替え
Prettier安定安定安定プラグインで
Biome安定部分(2.x)未対応未対応(直接)
dprintベータプラグインベータ未対応未対応

判断ガイド

  • Tailwind中心、CSS Modules — Prettier + prettier-plugin-tailwindcss + stylelint(最も検証済み)
  • 純粋なCSS、モノレポ速度重要 — Biome 2 CSSフォーマット + lint、stylelint補助
  • SCSSを深く使う — Prettier + stylelint(BiomeのSCSSはまだ部分的)

一行まとめ:CSSはまだPrettier + stylelintの組み合わせが最も安全。Biome 2は速く追いつくが、SCSS・Tailwind統合にはもう少し時間が必要。


10章 · 比較マトリックス — 一目で見る2026

項目Prettier 4Biome 2dprintRuffoxlintESLint v9stylelint v16
言語JS/TS/CSS/MD/YAML/JSON/Vue/Svelte/AstroJS/TS/JSX/JSON/CSS/GraphQLJS/TS/JSON/MD/TOML/DockerfilePythonJS/TSJS/TSCSS/SCSS/Less
フォーマッタありありあり(コア)ありなしなし(deprecated)なし
リンタなしありなしありありありあり
実装言語JS + Rust(v4)RustRust + WASMRustRustJSJS
速度(相対)1倍(v4 Rust 5〜15倍)25〜35倍10〜30倍50〜100倍50〜80倍1倍1倍
単一設定部分完全完全(フォーマットのみ)完全部分部分部分
プラグインエコシステム巨大小さいなし(内蔵)小さい巨大巨大
自動修正フォーマットのみフォーマット + 一部lintフォーマットのみ広範一部広範一部
エディタ統合最高良い良い最高良い最高良い
導入費用(既存チーム)なし(既に使用)低(補完)なし(既に使用)なし
推奨用途すべてのJS/TS、広いファイル形式JS/TS統合、速度優先多言語モノレポPythonほぼ全部速い1次lint深いlint、プラグイン活用CSS全般

一行まとめ

  • Prettier 4 — 安定性とエコシステムのチャンピオン、Rustバックエンドで速度改善
  • Biome 2 — JS/TS統合ツールの先頭、単一設定の価値
  • dprint — 多言語フォーマッタ、モノレポで強い
  • Ruff — Pythonツールチェインの実質標準
  • oxlint — ESLint速い1次通過、ビルドツールのコンポーネント
  • ESLint v9 — flat configで整理、プラグインエコシステムの深さ
  • stylelint v16 — CSSリンティングのデフォルト、Biomeが追いつき中

11章 · マイグレーション — 実シナリオ3つ

シナリオA · Prettier + ESLint → Biome 2(Next.jsモノレポ)

# 1. Biomeインストールと初期化
npm i -D --save-exact @biomejs/biome
npx biome init

# 2. Prettier設定マイグレーション
npx biome migrate prettier --write
# 3. ESLint設定マイグレーション(可能な部分のみ)
npx biome migrate eslint --write

# 4. 初回フォーマット(大きなdiff一度)
npx biome format --write .

# 5. リント点検
npx biome lint .

# 6. CI / package.jsonスクリプト変更
# "lint": "biome lint .",
# "format": "biome format --write ."

現場報告:

  • 50パッケージのモノレポでCI lintステージ90秒 → 6秒
  • マイグレーション作業1.5日(ルール差を埋める作業)
  • ESLintを完全には捨てず、type-awareルールの一部はESLint補助として残す
  • PrettierとBiomeの意見の微妙な差(長い表現の改行)でコードdiffが発生、一度に処理

移行すべきでないサイン:

  • eslint-plugin-jest、eslint-plugin-storybookといった外部プラグイン依存が深い
  • Vue / Svelte / Astroファイルの比重が大きい
  • チームがPrettier設定に満足、速度の不満なし

シナリオB · black + flake8 + isort → Ruff(Djangoモノレポ)

# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py312"

[tool.ruff.lint]
extend-select = ["E", "W", "F", "I", "B", "UP", "DTZ", "S", "RUF"]
ignore = ["E501"]

[tool.ruff.format]
quote-style = "double"
# 1. インストール
uv add --dev ruff

# 2. pyproject.toml設定
# (上記のとおり)

# 3. 初回フォーマット(blackと95%一致、diff一度)
ruff format .

# 4. lint + 自動修正
ruff check --fix --unsafe-fixes .

# 5. pre-commitフック単純化
# - id: ruff
#   args: [--fix]
# - id: ruff-format
# (以前は black、flake8、isort、pyupgrade、autoflake の5つ)

現場報告:

  • 30万行のDjangoコードベースでpre-commit 90秒 → 3秒
  • マイグレーション0.5日(black diff一度、ルールセレクタマッピング)
  • mypyは維持(Ruffは型チェッカではない)
  • チームの満足度が高く、ほぼすべてのPythonプロジェクトが同じパターンを採用

移行すべきでないサイン:ほとんどない。Pythonではほぼデフォルト。

シナリオC · 多言語モノレポ → dprint + Biome + Ruff(混在)

大企業のモノレポには、TS、Python、Markdown、TOML、Dockerfile、K8s YAMLが共存する。一つのツールで全部をカバーできなければツールを分業。

フォーマット:
  TS / JS / JSON / CSS  → Biome format
  Python                  → Ruff format
  Markdown / TOML / Dockerfile → dprint

リント:
  TS / JS               → Biome lint (速い) + ESLint (CI、深い)
  Python                → Ruff
  CSS                   → stylelint

CI統合:
  段階1: dprint check + biome check + ruff check (全て5〜10秒)
  段階2: ESLint --max-warnings 0 (CIのみ、1〜2分)
  段階3: 型チェック (tsc、mypy/ty)

現場報告:ツールが3つになるが、各ツールが得意な場所に置く。pre-commitフックは速いツールだけ、深い点検はCI。

一行まとめ:マイグレーションは一度に全部移行する必要はない。速いツールが得意な場所から段階的に、既存ツールは深い検証用に残すパターンが最も安全。


12章 · アンチパターンと落とし穴

速いツール導入時によく出会う落とし穴。

「Biome一行で全部解決するはず」

  • 症状:ESLintを完全に削除、プラグインルールも一気に捨てる
  • 結果:type-awareルール(no-floating-promises)とプラグインルールの不在。潜在バグが検出されない
  • 代わりに:速いlint = Biome、深いlint = ESLint補助を維持。段階的に吸収

「Ruff formatはblackと100%同じ」

  • 症状:大きなPRで初めて ruff format を実行した時にdiff 0を期待
  • 結果:95%一致、エッジケースでdiff発生。PRが汚れる
  • 代わりに:マイグレーション専用PRを一つ作って一度にフォーマット適用

「Prettierを外すとエディタが不便になる」

  • 症状:Biomeに移行後、VS Codeでformat on saveが効かない
  • 結果:設定漏れ。チームメンバーごとに異なるフォーマットがcommitされる
  • 代わりに:.vscode/settings.json"editor.defaultFormatter": "biomejs.biome" を追加、Biome拡張を必須化

「Rustツールは常に速いからキャッシュは不要」

  • 症状:CIでcargo cache、plugin cacheを無視。毎ビルドごとにダウンロード
  • 結果:ツール自体は速いがダウンロード段階が30秒〜1分追加
  • 代わりに:Biome / Ruffバイナリのキャッシュ、dprint plugin cacheの活用

「リンタが速いからルールを全部有効に」

  • 症状:Biome correctness.all、Ruff select = ["ALL"]
  • 結果:false positive爆発、チームが無視し始める
  • 代わりに:recommendedから始め、本当に必要なルールだけ追加。すべてのルールはポリシー

「pre-commitフックに全部入れよう」

  • 症状:huskyにbiome + eslint + ruff + tsc + jestを全部入れる
  • 結果:コミット1回20秒〜1分。開発者が --no-verify で迂回
  • 代わりに:pre-commitは速いものだけ(フォーマット、速いlint)。深い点検はCIに

「Biome migrateは完璧だろう」

  • 症状:biome migrate eslint を一度走らせて完了とする
  • 結果:マッピングできなかったルールは無視される。潜在バグの検出漏れ
  • 代わりに:マイグレーション後にdiffを人が確認、どのルールが落ちたか記録

「単一ツール = 単一の真実」

  • 症状:「Biomeが標準」と決めるが、Prettier出力と少し違う部分でチームが衝突
  • 結果:一部のチームメンバーはPrettierインストール、他のメンバーはBiomeインストール、コミットごとにdiff
  • 代わりに:ツール選定はチーム合意、.editorconfig + lockfile + 拡張機能必須で強制

「Rustバックエンド = 無条件に速い」

  • 症状:小さな単一ファイルではBiome呼び出しがPrettierより遅い場合がある(起動コスト)
  • 結果:マイクロベンチマーク結果だけ見て決定
  • 代わりに:実際のワークフロー(モノレポ全体フォーマット)で測定

「フォーマッタ・リンタを統合すれば意見が衝突しない」

  • 症状:Biome formatとESLint stylisticルール(中括弧位置など)を同時に有効化
  • 結果:無限ループ(format → lintエラー → 自動修正 → format再度)
  • 代わりに:フォーマットツールを単一に決め、lintではstylisticルールを削除

13章 · 意思決定ツリー — 私たちのチームは何を選ぶべきか

開始:
|
+- 言語はPython?
|   +- はい → Ruff(ほぼ全ての場合)。mypy/tyは別途
|
+- JS/TS中心?
|   |
|   +- 新規プロジェクト、シンプルなルール、速度優先
|   |   +- Biome 2 単独
|   |
|   +- 既存のPrettier+ESLint、満足、速度不満なし
|   |   +- そのまま維持(Prettier 4 Rustバックエンドオプションを有効化)
|   |
|   +- 既存のPrettier+ESLint、速度が真の問題
|   |   +- プラグインを深く活用 → Prettier + Biome lint(速い1次) + ESLint(深い)
|   |   +- プラグイン少ない → Biome 2へ移行
|   |
|   +- Vue / Svelte / Astroの比重大
|   |   +- Prettier維持(Biome未対応領域)
|   |
|   +- 速い事前点検を追加
|       +- oxlintをhusky pre-commitに
|
+- 多言語モノレポ(TS + Python + インフラ)
|   +- ツール分業:
|      - TS → BiomeまたはPrettier
|      - Python → Ruff
|      - インフラ(TOML、Dockerfile、MD)→ dprint
|
+- CSS / Tailwind中心
|   +- Prettier + prettier-plugin-tailwindcss + stylelint
|
+- モノレポ全体lintが分単位
    +- 1次速い通過を導入:
       - Biome / Ruff / oxlintをhusky pre-commitとCI第1段階に
       - 既存ツールはCI後半の深い点検用に

シンプルなルール

  • Python → Ruff
  • 新規JS/TSプロジェクト、シンプル → Biome 2
  • 既存のPrettier+ESLintがうまく動いている → 維持
  • モノレポlintが本当に遅い → 速い1次通過を導入
  • 多言語 → ツール分業
  • Tailwind / Vue / Svelte / MDXの比重大 → Prettier維持

エピローグ — チェックリスト、アンチパターン、次回予告

2026年のフォーマッタ・リンタ地形は5年前と違う。Rust再実装の波でツールが10〜100倍速くなり、「フォーマッタがリンタを吸収する」統合の流れが本格化した。Biome 2とRuffがそれぞれの領域で実質標準に近づき、Prettier 4はRustバックエンドで応答し、ESLint v9はflat configで自分の場所を整理した。

しかし「一つのツールですべて終わり」という絵はまだない。プラグインエコシステム、非標準ファイル対応、type-aware解析といった領域で既存ツールが生き残る。自分のチームに合う選択は — 何が真の障害で、どのトレードオフを受け入れるか — 測定から始まる。

ツール選択チェックリスト

  1. 現在のlint・フォーマット時間が本当に問題か? — 30秒が1秒になって何が変わるか測定
  2. 言語別の事情は違うか? — Pythonはほぼ決着、JS/TSはより複雑
  3. プラグイン依存が深いか? — eslint-plugin-* を深く使うならESLint維持が安全
  4. モノレポ / 多言語 / 非標準ファイル? — dprintまたはツール分業を検討
  5. マイグレーションは一度に vs 段階的? — 大きなPRは別途マイグレーションPRに
  6. pre-commit vs CI分離 — 速いツールだけpre-commit、深いツールはCIに
  7. type-aware lintが必要か?no-floating-promises 類はtypescript-eslint維持
  8. エディタ統合は動くか? — VS Code / JetBrains拡張の成熟度確認
  9. CIでツールのキャッシュが効くか? — 速いツールでもダウンロード段階のキャッシュが必要
  10. チーム合意があるか? — 一部だけBiomeを使うとcommit衝突

アンチパターン

アンチパターンなぜ悪いか代わりに
Biome一行でESLint完全削除type-awareルール、プラグイン不在速いlint + 深いlint分離
Ruff formatがblackと100%同じと仮定95%一致、エッジケースdiffマイグレーションPR別途
全ルール有効化(ALL)false positive爆発、無視開始recommendedから開始、必要なものだけ
pre-commitに全検査コミット1分、--no-verify 迂回速いものだけpre-commit、深いものはCI
Rustツールはキャッシュ不要ダウンロード段階が30秒〜1分バイナリ / プラグインキャッシュ
Biome migrate後の確認なしマッピングされないルール損失diff人間レビュー
単一ツール強制、チーム合意なし一部のみ導入、diff衝突合意後にlockfile / 拡張推奨
マイクロベンチマークだけ見て決定実ワークフローと違うモノレポ全体時間で測定
フォーマット・lint stylistic衝突無限ループフォーマット単一化、lint stylistic削除
Prettier 4 Rustバックエンドを即依存ベータ段階の変動性安定確認後に導入

次回予告

次回は**「2026年のビルドツール — Vite、Turbopack、Rspack、Rolldown、esbuild、swc、oxcの実情」**。本稿が「コードをどう整えるか」の話なら、次回は「コードをどう束ねるか」の話だ。esbuildのGo、swc/TurbopackのRust、Vite の esbuild+Rolldown への移行、RspackのRust再実装、oxcのコンポーネント化 — 同じRust再実装パターンがビルドツールでどう繰り返されるか、そして何を選ぶべきかを整理する。


参考 / References

현재 단락 (1/483)

`prettier --write .` の一行で完結する時代があった。2020年頃の話だ。それから5年経つうちに、同じコマンドはモノレポで30秒、CIで2分まで膨らんだ。`eslint --max-...

작성 글자: 0원문 글자: 22,260작성 단락: 0/483