- Published on
2026年のフォーマッタとリンタ — Biome、dprint、Ruff、oxc、Prettier 4、ESLint v9の実情
- Authors

- Name
- Youngju Kim
- @fjvbn20031
プロローグ — なぜまたフォーマッタ・リンタの話か
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 / TS | Prettier + ESLint | Prettier + ESLint v9、Biome 2 | oxc、dprint |
| Python | black + flake8 + isort + pylint | Ruff(format + lint) | ty(型チェッカ) |
| Rust | rustfmt + clippy | rustfmt + clippy | — (既にRust) |
| Go | gofmt + golangci-lint | 同じ | — |
| CSS / SCSS | Prettier + stylelint | Prettier + stylelint、Biome 2 | dprint、oxc |
| Markdown | Prettier、remark-lint | Prettier、dprint | — |
| TOML / YAML / JSON | Prettier | dprint、taplo、yamlfmt | — |
| 多言語モノレポ | Prettier + ESLint | dprint(統合フォーマッタ)、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
なぜここまで差がつくのか
- 言語自体の差 — JSツールはV8 JIT上で動くインタプリタコード、Rustツールはネイティブバイナリ。これだけで3〜10倍
- 単一パスの解析 — 従来ツールはlex→parse→AST変換を複数回行う。Biome/oxc/Ruffは一度のパスでlossless concrete syntax tree(CST)を作り、すべての解析で再利用
- 並列化 — Rustのデータ並列性を活かしてファイルを真に並列で処理。JSツールはシングルスレッドで、Workerプールを使ってもシリアライズ費用がかかる
- メモリレイアウト — CSTノードをcache-friendlyな配列に格納(rowan、oxc-resolverといったライブラリ)。アロケーションが少ない
- 再起動コスト — 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 prettier、biome 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) |
|---|---|---|
| Ruff | flake8、isort、black、pydocstyle、... | 安定、広範囲採用 |
| uv | pip、virtualenv、pip-tools、pipx、poetry(一部) | 安定、急速拡散 |
| ty | mypy、pyright(部分) | アルファ/ベータ |
| rye | poetry、hatch(概念的) | uvに吸収中 |
全体パターン:「ツール一つが速ければそのツール中心にすべてのワークフローが再編成される」。同じパターンがBiome(JS)、oxc(JS)で繰り返される。
一行まとめ:RuffはPythonツールチェインで実質デフォルトになった。理由はシンプル — 速く、統合されており、マイグレーション費用が低い。
6章 · oxc — Rust JavaScriptツールチェインファミリ
oxcは別の野心だ。Boshenが率いるプロジェクトで、JavaScriptツールチェイン全体をRustで作る。パーサ、リゾルバ、トランスフォーマ、リンタ、フォーマッタ、ミニファイア。Biomeが「単一ユーザツール」なら、oxcは「他のツールが使うコンポーネントライブラリ」に近い。
oxcの構成要素
| コンポーネント | 役割 | 比較対象 |
|---|---|---|
| oxc-parser | JS/TSパーサ | acorn、esprima、swcパーサ |
| oxc-resolver | モジュール解決 | enhanced-resolve |
| oxc-transformer | JS/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 — 何が違うか
| 比較 | Biome | oxc |
|---|---|---|
| 目標 | 統合ユーザツール | コンポーネントライブラリ + ツールファミリ |
| 単一設定 | あり(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 4 | Biome 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-promises、await-thenable、no-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フォーマット — 誰が得意か
| ツール | CSS | SCSS | Less | Tailwindクラス並べ替え |
|---|---|---|---|---|
| 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 4 | Biome 2 | dprint | Ruff | oxlint | ESLint v9 | stylelint v16 |
|---|---|---|---|---|---|---|---|
| 言語 | JS/TS/CSS/MD/YAML/JSON/Vue/Svelte/Astro | JS/TS/JSX/JSON/CSS/GraphQL | JS/TS/JSON/MD/TOML/Dockerfile | Python | JS/TS | JS/TS | CSS/SCSS/Less |
| フォーマッタ | あり | あり | あり(コア) | あり | なし | なし(deprecated) | なし |
| リンタ | なし | あり | なし | あり | あり | あり | あり |
| 実装言語 | JS + Rust(v4) | Rust | Rust + WASM | Rust | Rust | JS | JS |
| 速度(相対) | 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、Ruffselect = ["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解析といった領域で既存ツールが生き残る。自分のチームに合う選択は — 何が真の障害で、どのトレードオフを受け入れるか — 測定から始まる。
ツール選択チェックリスト
- 現在のlint・フォーマット時間が本当に問題か? — 30秒が1秒になって何が変わるか測定
- 言語別の事情は違うか? — Pythonはほぼ決着、JS/TSはより複雑
- プラグイン依存が深いか? — eslint-plugin-* を深く使うならESLint維持が安全
- モノレポ / 多言語 / 非標準ファイル? — dprintまたはツール分業を検討
- マイグレーションは一度に vs 段階的? — 大きなPRは別途マイグレーションPRに
- pre-commit vs CI分離 — 速いツールだけpre-commit、深いツールはCIに
- type-aware lintが必要か? —
no-floating-promises類はtypescript-eslint維持 - エディタ統合は動くか? — VS Code / JetBrains拡張の成熟度確認
- CIでツールのキャッシュが効くか? — 速いツールでもダウンロード段階のキャッシュが必要
- チーム合意があるか? — 一部だけ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
- Biome公式サイト
- Biome v2発表 — Multi-file analysis, Plugins, and more
- Biomeマイグレーションガイド
- Biome vs Prettierベンチマーク
- Biome lintルール索引
- dprint公式サイト
- dprintプラグイン索引
- Ruff公式ドキュメント
- Ruffルール索引
- Astralブログ — Ruff format発表
- Astralブログ — ty型チェッカ
- Astral uv公式ドキュメント
- oxc公式サイト
- oxlintドキュメント
- oxc GitHubリポジトリ
- Prettier公式サイト
- Prettier 4発表ノート
- Prettierプラグイン索引
- ESLint v9発表
- ESLint flat configマイグレーション
- typescript-eslint v8発表
- typescript-eslint projectServiceガイド
- stylelint公式サイト
- Charlie Marsh — Ruff origin storyインタビュー
- Rome → Biome移行発表
- Sebastian McKenzie — Romeの終了
- Boshen — oxc紹介記事