Contents
In brief
In 2026, many teams evaluate Biome and Oxlint as replacements for the ESLint + Prettier stack. Both are Rust binaries that traverse code tens of times faster than JavaScript tooling. Speed alone does not decide the winner: Biome unifies formatting and linting in one config, while Oxlint preserves ESLint plugins and incremental migration paths. The right pick depends on custom rules and how much TypeScript type information you need at lint time.
What happened
The JavaScript tooling layer hit a performance ceiling. ESLint with type-aware rules on a 50k LOC codebase can take 30–60 seconds; Prettier adds another 5–10. In monorepos with many packages, those delays multiply and linting becomes the pre-commit and CI bottleneck.
Biome (evolved from the Rome Tools idea) merges formatting and linting into one native binary. Two hundred-plus built-in rules cover correctness, style, and performance; many rules from eslint-plugin-react and eslint-plugin-import map directly. The hard limit: no custom plugins — internal rules for APIs, security, or frameworks block a Biome migration.
Oxlint, part of the Oxc project, maximizes ESLint compatibility while delivering extreme speed. Existing .eslintrc.json files and plugins like @typescript-eslint, react-hooks, and import work with minimal edits. Formatting stays on Prettier or similar. The Oxc parser builds an AST once and batches rule execution — hence ~2 seconds on 100k LOC versus minutes for ESLint.
The Dev.to comparison outlines four team profiles: proprietary ESLint plugins → Oxlint; full type-aware linting → Oxlint with TypeScript; toolchain consolidation → Biome; cautious incremental migration → Oxlint first, consolidate later.
Why it matters
When linting takes seconds instead of minutes, daily workflows change: save-on-type in the editor stops lagging, pre-commit hooks stop getting --no-verify, and CI can parallelize monorepo packages without a serial ESLint gate.
For TypeScript the tradeoff is sharper. ESLint with @typescript-eslint/recommended loads the full type graph — expensive but thorough. Biome uses fast-path analysis: common mistakes at full speed, but complex generics and conditional types can slip through. Oxlint can run true type-aware linting via the TypeScript compiler — 10–20× slower than bare Oxlint, still far faster than classic ESLint.
| Criterion | Biome | Oxlint | Classic ESLint |
|---|---|---|---|
| Speed | Very high | Highest | Low on large codebases |
| Formatting | Built in | Separate tool | Prettier separately |
| Custom plugins | No | Yes (compat layer) | Yes |
| Type-aware | Approximate | Full (optional) | Full |
| Migration | Rewrite config | Minimal edits | — |
In practice
- Inventory — list
.eslintrcrules and flag custom plugins. Any proprietary plugin rules out Biome for now. - Pilot one package — swap
eslint .foroxlintinpackage.json, or generatebiome.jsonand drop duplicate Prettier/ESLint deps after validation. - CI — Biome exposes
biome ci(format + lint atomically); Oxlint needs separateoxlintandprettier --checksteps that can disagree on edge cases. - TypeScript-heavy codebases — if generics and conditional types are safety-critical, benchmark Oxlint with type-checking; if TS is mainly for editor hints, Biome may suffice.
- Greenfield — new repos without legacy plugins often start with Biome to avoid dual config drift.
Minimal starter biome.json:
{
"$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
"formatter": { "enabled": true, "indentWidth": 2, "lineWidth": 100 },
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": { "noUnusedVariables": "error" }
}
}
}
Takeaway
Rust rewrites of JavaScript tooling respond to an architectural limit of Node.js as an AST parser host. Biome and Oxlint are not direct competitors: one simplifies the stack, the other accelerates the ESLint world you already have. Before migrating, answer whether you need custom rules and full type-checking at lint time — that usually picks the tool for you.