Biome vs ESLint + Prettier in 2026: Is the All-in-One Linter Worth Switching?

The biome vs eslint debate has shifted in 2026. Biome is no longer a promising experiment — it's production-ready, widely adopted, and fast enough that "we'll migrate later" is starting to sound like technical debt. But ESLint's plugin ecosystem is massive, and Prettier is still the formatting standard for teams that haven't moved.

Here's the actual comparison, run on a real React + TypeScript project: 47,000 lines across 180 files, using Biome 1.9 and ESLint 9 (flat config) + Prettier 3.x.

Speed: It's Not Even Close

Biome formats and lints in a single pass, written in Rust. That matters more than the benchmarks suggest, because the speed stays consistent regardless of codebase size.

On the test project:

  • ESLint + Prettier (with cache): ~4.2s lint, ~2.8s format = ~7s total
  • Biome check (lint + format): ~0.4s

That's a 17× speedup with cache on ESLint's side. Cold runs — typical in CI — were worse: ESLint hit 11s, Biome stayed under 0.5s. In a pre-commit hook or CI pipeline, this compounds. Shaving 10+ seconds off every push is real developer time, not synthetic benchmark noise. The React + Biome + GitHub Actions setup guide covers exactly how tight this makes the CI feedback loop when you pair it with Vitest.

Config Complexity: The Real Selling Point of Biome vs ESLint

This is where the ESLint ecosystem gets embarrassing. A standard React/TypeScript setup requires:

npm install -D eslint @eslint/js eslint-plugin-react eslint-plugin-react-hooks \
  @typescript-eslint/eslint-plugin @typescript-eslint/parser \
  eslint-config-prettier prettier

Then you write eslint.config.js, .prettierrc, possibly .editorconfig, and spend 20 minutes figuring out why the TypeScript parser version disagrees with ESLint on something the docs don't mention. I've hit this on fresh projects — it's a genuinely bad first hour that has nothing to do with actual engineering.

Biome's equivalent:

npm install -D @biomejs/biome
npx biome init

Your entire config lives in one biome.json:

{
  "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "error"
      }
    }
  },
  "formatter": {
    "indentStyle": "space",
    "indentWidth": 2
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "es5"
    }
  }
}

No plugin resolution, no parser config, TypeScript and JSX work natively. IDE support is solid — JetBrains WebStorm has had first-class Biome integration since 2024, and the VS Code extension is actively maintained. For monorepos specifically, Biome's config inheritance is clean enough to justify the switch on its own. The pnpm workspaces + Biome guide covers that pattern in detail.

Rule Coverage: Where ESLint Still Has the Edge

Biome ships around 300+ rules. ESLint with its plugin ecosystem has thousands. For most projects the gap doesn't matter in practice — but for some teams it's a dealbreaker.

What Biome doesn't cover:

  • eslint-plugin-jsx-a11y — no accessibility rules. If WCAG compliance is a requirement, this is a significant gap, not a minor inconvenience.
  • eslint-plugin-testing-library and eslint-plugin-jest-dom — useful for enforcing correct Vitest/Testing Library query patterns. Biome won't catch getByTestId misuse or stale waitFor patterns.
  • Custom organisational plugins — Biome has no plugin API yet. Internal ESLint rules for codebase conventions don't migrate. Full stop.
  • eslint-plugin-import granularity — Biome handles import sorting, but fine-grained grouping rules (local vs. external vs. internal path aliases) aren't as configurable.

For the majority of React/TypeScript products, Biome's recommended ruleset catches what matters: unused variables, React Hooks violations, TypeScript correctness, and suspicious patterns. The high-value catches are covered. But if your team is building a public-facing product with strict accessibility requirements, or you have internal ESLint plugins encoding team conventions — ESLint + Prettier is still the honest recommendation. Don't switch just to switch.

Migration Reality: Budget More Than a Day

On the 47k-line test project, biome migrate eslint and biome migrate prettier handled roughly 80% of the config translation automatically. The remaining 20% was rules with no Biome equivalent — either dropped or mapped manually. The docs don't comprehensively cross-reference ESLint rules to Biome equivalents, so you'll be doing some lookup work that Stack Overflow won't always help with.

Formatting differences are real. Biome and Prettier don't produce identical output, particularly with complex JSX. The migration generates a large diff — commit it separately, get team buy-in upfront, and make sure your error monitoring setup isn't relying on stale source maps. If you're using Sentry for production error tracking, re-upload your source maps after the formatting migration commit, otherwise stack traces will point to wrong line numbers.

The Verdict

Use Biome if you're starting a new React/TypeScript project, working in a monorepo, or your team's primary pain point is config maintenance and slow CI. The speed alone justifies it for new projects, and rule coverage is sufficient for most product codebases.

Stick with ESLint + Prettier if you need jsx-a11y, have custom internal ESLint plugins, or are maintaining a large existing project where a formatting migration diff creates more risk than the speed gain removes. ESLint 9's flat config is a genuine improvement — the ecosystem advantage is still real for teams that need it.

The decision is clearest on new projects: there is no good reason to reach for ESLint + Prettier on a greenfield React/TypeScript setup in 2026. Biome is faster, simpler to configure, and mature enough to trust in production. The ecosystem gap narrows with each Biome release. The performance gap doesn't.

H