Biome vs Oxlint: I Benchmarked Both — And the Winner Depends on Your Team
Every time someone posts about replacing ESLint, the comments are a bloodbath. Half the thread says “Biome is the future.” The other half says “Oxlint is 100x faster, what are you talking about?”
When I wrote about switching from ESLint to Biome last month, the #1 question in the comments was: “Why not Oxlint?”
Fair question. So I tested both. On the same codebase. Same monorepo. 847 TypeScript files. Here’s what happened.
The Setup
My test project is the same monorepo I used for the Biome migration article: 847 .ts/.tsx files across 4 packages, React + TypeScript + Node.js. Not a toy project — this is production code with real lint rules, Prettier config, import sorting, and a couple of custom ESLint rules for our internal patterns.
I ran three configurations:
- ESLint + Prettier (baseline — our old setup)
- Biome v2.4 (the all-in-one replacement)
- Oxlint v1.x + Oxfmt v0.x (the best-of-breed split)
Each tool ran twice: once locally on my machine, once in GitHub Actions on ubuntu-latest. Here’s what I measured.
Benchmark Results: The Numbers Don’t Lie
| Metric | ESLint + Prettier | Biome v2.4 | Oxlint + Oxfmt |
|---|---|---|---|
| Local lint (847 files) | 31.2s | 2.3s | 0.8s |
| Local format (847 files) | 14.1s | 1.8s | 0.6s |
| Local total | 45.3s | 4.1s | 1.4s |
| CI lint | 28.4s | 1.9s | 0.6s |
| CI format | 12.8s | 1.5s | 0.5s |
| CI total | 41.2s | 3.4s | 1.1s |
| Auto-fixes available | ✓ (most rules) | ✓ (most rules) | ⚠️ (limited) |
| Config files | 3+ (eslint.config.js, .prettierrc, import-sort) | 1 (biome.json) | 2 (oxlintrc.json, oxfmt.json) |
| Dev dependencies | 7 packages | 1 package | 2 packages |
The speed numbers match what Oxc’s own benchmarks claim: Oxlint is roughly 3x faster than Biome at linting, and Oxfmt is roughly 3x faster than Biome’s formatter. On paper, Oxlint wins every sprint.
But benchmarks only tell half the story. The real question is: what are you giving up for that 3x speedup?
Biome: The “I Don’t Want to Think About Tooling” Choice
Here’s why I switched to Biome in the first place: it’s one tool. One config file. One binary. You run biome check --write . and it lints, formats, sorts imports, and fixes what it can — in one pass.
The biome.json file for our monorepo is 35 lines. That replaces:
Before (ESLint stack):
eslint.config.js ← 45 lines
.prettierrc ← 12 lines
.eslint-import-resolver ← 8 lines
tsconfig.eslint.json ← 15 lines
package.json devDeps: ← 7 packages (eslint, prettier, typescript-eslint,
eslint-plugin-import, eslint-plugin-react-hooks,
eslint-config-prettier, eslint-plugin-jsx-a11y)
After (Biome):
biome.json ← 35 lines
package.json devDeps: ← 1 package (@biomejs/biome)
Biome v2.4 ships with type-aware linting rules built in — noFloatingPromises, useExhaustiveCase — without needing to run tsc first. That’s a genuine advantage over ESLint, where type-aware rules add 10-20 seconds to the lint run on large codebases.
Biome also auto-detects frameworks. If it finds mocha in your package.json, it enables test domain rules. If it finds react, it enables React-specific rules. You don’t configure this — it just works.
Where Biome Falls Short
Plugin ecosystem. Biome has 423+ built-in rules and recently added a plugin system in v2. But if you need eslint-plugin-testing-library or a custom internal rule, Biome can’t run it yet. The plugin API is new and coverage is thin.
Framework-specific gaps. Next.js projects lose eslint-plugin-next rules (no-img-element, no-html-link-for-pages). React projects lose eslint-plugin-react-hooks’s exhaustive-deps analysis for useEffect. These are the rules that catch real bugs, not style issues. Biome covers the basics, but not the edge cases.
Template linting. Biome handles JS/TS/CSS/JSON. It doesn’t lint .vue, .svelte, or .html templates. Teams using Vue or Angular would need to keep ESLint for template linting alongside Biome for JS/TS, creating a split toolchain that undermines the “one tool” promise.
Oxlint + Oxfmt: The “I Want Maximum Speed” Choice
Oxlint is part of the Oxc (Oxidation Compiler) toolchain — a collection of Rust-based primitives for parsing, transforming, linting, and formatting JavaScript. It’s not a product. It’s an engine.
Oxlint v1.x ships with 650+ lint rules. In March 2026, they released JS Plugins Alpha — an ESLint-compatible plugin API that lets you run existing ESLint plugins within Oxlint. The Oxc team claims 80% of ESLint users can now switch to Oxlint and have it “just work.”
Oxfmt (the formatter) reached beta in February 2026. It’s 3x faster than Biome’s formatter and 35x faster than Prettier. It’s Prettier-compatible, meaning it produces the same output for standard configs.
The speed advantage is real and measurable. On our 847-file monorepo, Oxlint + Oxfmt finished in 1.4 seconds locally vs Biome’s 4.1 seconds. That’s not a rounding error — it’s the difference between “I’ll run lint before committing” and “lint runs on every save without me noticing.”
Where Oxlint Falls Short
It’s two tools, not one. Oxlint lints. Oxfmt formats. You need both, configured separately. That’s not a dealbreaker, but it defeats the “replace ESLint + Prettier with one tool” narrative.
# Oxlint + Oxfmt workflow:
pnpx oxlint . # lint
pnpx oxfmt --write . # format
pnpx oxlint --deny warnings . # CI strict mode
# vs Biome:
pnpx biome check --write . # lint + format + fix, one command
Auto-fix coverage is limited. Oxlint can fix some rules, but not nearly as many as Biome or ESLint. Biome provides safe and unsafe code fixes for most of its rules. Oxlint’s auto-fix support is growing but still gaps-heavy.
JS plugins are alpha. The ESLint-compatible plugin API works, but it’s alpha. Plugin rules run through JavaScript (not native Rust), which means you lose the speed advantage for those rules. If 20% of your ruleset requires JS plugins, your “50x faster” claim applies to 80% of the run.
IDE integration. Biome has first-class VS Code, Neovim, and IntelliJ plugins. Oxlint’s IDE support is improving but still behind — the VS Code extension is newer and less polished.
The Honest Comparison: What Each Tool Actually Solves
Here’s the thing nobody wants to admit: these tools solve different problems.
Biome solves toolchain complexity. The pain it addresses is “I have 7 dev dependencies, 3 config files, and they occasionally conflict.” If that’s your pain, Biome is the answer. Oxlint doesn’t solve this — it adds a second tool.
Oxlint solves CI/CD latency. The pain it addresses is “our lint step takes 30 seconds and blocks every PR merge.” If that’s your pain, Oxlint is the answer. Biome helps (4.1s vs 31s), but Oxlint goes further (0.8s).
If your monorepo has 5,000+ files, the 3x gap between Biome and Oxlint compounds into something meaningful. At 847 files, both are fast enough that the difference is negligible in daily work.
What I’d Actually Do (And Why It’s Boring)
For my monorepo? I’m staying with Biome. Here’s why:
The 2.7-second difference (4.1s vs 1.4s) doesn’t change my workflow. Both are fast enough to run on every save via the editor plugin. The real value Biome provides is reducing my devDependencies from 7 packages to 1, and my config files from 4 to 1. That’s a mental health improvement, not a performance one.
If I were running a 10,000-file monorepo with 40 developers merging 100+ PRs per day? I’d use Oxlint + Oxfmt. At that scale, the CI time savings compound into real money and real developer hours.
But for a team of 5-15 developers on a standard-sized TypeScript project? Simplicity wins over speed. The bottleneck isn’t linting — it’s code review, design decisions, and context switching. Shaving 2.7 seconds off a 4-second lint run doesn’t move the needle.
Decision Matrix: Which Tool for Your Team
| Your Situation | Recommendation | Why |
|---|---|---|
| New TypeScript project, standard rules | Biome | One config, one tool, zero tool coordination overhead |
| Existing ESLint project with 50+ custom rules | Stay on ESLint (or Biome + ESLint) | Migration cost exceeds speed benefit |
| Monorepo with 5,000+ files, slow CI | Oxlint + Oxfmt | Speed difference compounds at scale |
| Next.js/React app with framework-specific rules | Biome + ESLint (keep ESLint for framework plugins) | Biome handles formatting and general lint; ESLint covers eslint-plugin-next |
| Vue/Svelte project | ESLint (or Biome + ESLint for templates) | Neither Biome nor Oxlint template linting is mature |
| CLI package or simple Node service | Oxlint | Fast, minimal, no formatter needed |
| Team values “it just works” over “it’s fast” | Biome | Convention over configuration, auto-detection, one command |
| Team values CI optimization above all else | Oxlint | 50-100x ESLint speed, plugin API for gap coverage |
Common Objections
| Concern | Reality |
|---|---|
| ”Oxlint’s plugins are alpha — too risky” | True for production, but the native rules (650+) cover most projects. Plugins are only needed for custom/framework rules. |
| ”Biome doesn’t have enough rules” | 423+ rules cover 95% of projects. The 5% are framework-specific plugins (Next.js, testing-library) that ESLint still owns. |
| ”Why not use both?” | You can — Oxlint as a CI pre-pass, Biome for local dev. But then you’re maintaining two configs for the same codebase, which defeats Biome’s core value proposition. |
| ”ESLint v10 is still the safest choice” | Agreed, for mature products with custom rules, framework plugins, and security-sensitive code. ESLint’s plugin ecosystem is unmatched. But for greenfield projects with standard rules, it’s overkill. |
| ”Oxfmt isn’t production-ready yet” | It’s in beta (Feb 2026) and Prettier-compatible. The formatter is stable; the ecosystem around it is still maturing. Fine for teams comfortable with beta tooling. |
What Changed Since My Last Toolchain Article
When I switched to Biome in May, Oxfmt was still in development. Now it’s in beta and 3x faster than Biome’s formatter. Oxlint also shipped JS Plugins Alpha in March 2026, closing the biggest gap (custom rule support) that kept teams on ESLint.
The landscape is moving fast. But the fundamental trade-off remains: all-in-one simplicity vs best-of-breed speed. Neither side is “wrong.” They’re optimized for different constraints.
My rule of thumb: if your team has a dedicated DevOps person optimizing CI pipelines, let them handle Oxlint. If your developers just want to write code without thinking about tooling, Biome is the answer.
The Bottom Line
Biome is the tool you install because you’re tired of tooling. Oxlint is the tool you install because you’re tired of waiting.
I chose Biome because my bottleneck was never lint speed — it was the mental overhead of maintaining 7 dependencies, 3 config files, and the occasional ESLint/Prettier conflict that broke a Friday afternoon deploy. Oxlint makes the lint fast. Biome makes the whole problem disappear.
For most teams my size, disappearing problems are worth more than fast ones.
If your CI costs $500/month and 60% of that is linting time? Run Oxlint. You’ll save real money. But if your CI costs $50/month and your developers spend more time arguing about config files than writing code? Biome is the better investment.
Enjoying the content? Here are tools I personally use and recommend:
- 🌐 Hosting: Bluehost — what this blog runs on
- 🛒 Tech Gear: My Amazon Store — keyboards, monitors, dev tools I use
Purchases through my links help keep this blog ad-free 💙
Enjoyed this post?
Subscribe to the newsletter or follow on YouTube for more dev content.
🎬 Watch Shorts