Back to blog
Programming
IntermediateForFrontend EngineersJavaScript EngineersPlatform Engineers
7 min

I Replaced ESLint + Prettier with Biome in 2026 — Here Is the Benchmark

A hands-on 2026 look at replacing ESLint and Prettier with Biome: what it is, the one-command migration, real benchmark numbers, what you actually lose, and an honest verdict on when to switch and when not to.

biomeeslintprettierrustlinterformatterbiome vs eslintbiome vs prettier
Contents

For more than a decade the answer to “how do I keep my JavaScript clean?” was the same two-headed reflex: install eslint, install prettier, then spend an afternoon wiring them together so they stop fighting each other. Add the TypeScript parser, an import plugin, a React plugin, an accessibility plugin, a config to disable the rules Prettier already handles, and you end up with a dozen dependencies and four config files just to format and lint code you have not written yet.

Biome collapses that entire stack into a single binary. It is a formatter, a linter, and an import sorter written in Rust, configured by one biome.json, fast enough that you stop thinking of “lint” as a step you wait for. This article is a hands-on look at what it actually replaces, how the migration really goes, what the benchmark numbers look like, and — just as important — what you give up when you switch.

Biome: delete ESLint and Prettier, ship one Rust binary that formats and lints your code.

This is the tooling half of a bigger 2026 theme — deleting the heavy defaults you installed on reflex. If you still carry lodash too, the same logic applies to your utilities: see Delete lodash: es-toolkit is 2x faster and 97% smaller.

What Biome actually is

Biome is the descendant of the Rome project: a toolchain for web languages built in Rust rather than JavaScript. Instead of a formatter here and a linter there, each with its own parser and its own config dialect, Biome parses your code once and runs everything against that single tree:

  • Formatter — an opinionated formatter in the Prettier tradition, with a compatible style for JavaScript, TypeScript, JSX, JSON, and CSS.
  • Linter — hundreds of rules covering correctness, suspicious code, style, and TypeScript, plus framework rules for React and accessibility.
  • Import sorting — deterministic import organization, no separate plugin required.

All of it ships as one dependency, @biomejs/biome, and reads one config file. That is the whole pitch: fewer moving parts, one source of truth.

Terminal window
npm install --save-dev --save-exact @biomejs/biome
npx biome init

biome init drops a biome.json with sensible defaults. From there, formatting and linting your project is a single command each:

Terminal window
npx biome format --write .
npx biome lint .
# or do both, plus import sorting, in one pass:
npx biome check --write .

The pain it removes: plugin soup

The reason Biome resonates is not novelty — it is fatigue. A mature ESLint + Prettier setup tends to look like this before you have configured a single rule of your own:

Before: eslint, prettier, and a stack of plugins with four config files. After: one Biome binary and one biome.json.

Every one of those packages has its own release cadence, its own peer-dependency demands, and its own way of breaking on a major version bump. The eslint-config and eslint-plugin matrix is a genuine maintenance tax: someone on the team owns keeping it consistent, and every upgrade is a small negotiation. The .eslintrc / .prettierrc split means two config dialects, and the classic footgun of Prettier and ESLint disagreeing about the same line until you add eslint-config-prettier to make them stop.

Biome replaces the whole diagram with two things: the @biomejs/biome binary and a biome.json. There is no plugin resolution step, no peer-dependency graph, and no formatter-versus-linter turf war, because the formatter and the linter are the same program.

The migration: one command, not a rewrite

The fear with any “replace your tooling” pitch is the migration cost. Biome answers it directly with built-in migration commands that read your existing configuration and translate it:

Terminal window
# translate your ESLint rules into biome.json
npx biome migrate eslint --write
# translate your Prettier options into biome.json
npx biome migrate prettier --write

These commands parse your .eslintrc and .prettierrc (including extends chains and overrides) and map them onto Biome’s equivalents, so your line width, quote style, semicolon preference, and the rules Biome supports all carry over. You review the resulting biome.json, delete the old config files and their dependencies, and wire Biome into your scripts:

{
"scripts": {
"format": "biome format --write .",
"lint": "biome lint .",
"check": "biome check --write ."
}
}

Add the official VS Code extension and set Biome as the default formatter, and the editor experience is the same “format on save” you already had — just faster and from one tool.

The benchmark

This is the part everyone actually wants, so let us be precise about what the numbers mean. Biome is fast because it is native Rust, parses each file once, and runs across all your cores. ESLint and Prettier pay Node.js startup, per-file plugin resolution, and single-threaded parsing on top of the actual work.

The chart below is scaled to the ratios in the official Biome benchmarks — it shows the shape of the difference on a large codebase, not a promise about your exact repo:

Benchmark: Biome formats roughly 25x faster than Prettier and lints around 20x faster than ESLint on the same codebase.

The headline from Biome’s own published benchmarks is that its formatter runs on the order of 25x faster than Prettier, and linting lands around 20x faster than ESLint. In practice the win shows up in two places:

  • CI — a lint-and-format check that used to take several seconds drops to a fraction of a second, which matters when it runs on every push across every PR.
  • The editor — format-on-save and lint-on-type feel instant even on large files, because there is no plugin pipeline to spin up.

The honest caveat: absolute times depend entirely on your codebase, your machine, and your rule set. Do not ship someone else’s number as your own. Measure it yourself — it takes two minutes:

Terminal window
# install hyperfine (brew install hyperfine) and compare wall-clock time
hyperfine --warmup 3 \
'npx prettier --write "src/**/*.{ts,tsx}"' \
'npx biome format --write src'
hyperfine --warmup 3 \
'npx eslint "src/**/*.{ts,tsx}"' \
'npx biome lint src'

The ratio in your terminal is the number that belongs in your team’s decision, and in my experience it lands in the same order of magnitude the official benchmarks report.

What you actually lose

Honesty matters more than hype, so here is the counter-case — the things you should weigh before you delete .eslintrc:

  • The plugin ecosystem. This is the big one. ESLint has thousands of community rules and framework-specific plugins. Biome covers the widely used ones and adds more every release, but if you depend on a niche plugin or a bespoke internal rule, there may be no Biome equivalent yet.
  • Custom rules. If your team wrote its own ESLint rules to enforce internal conventions, those do not port. Biome’s plugin story is growing, but it is not the same open-ended eslint-plugin model.
  • Long-tail language and format support. Biome’s language coverage (JS/TS/JSX/JSON/CSS and expanding) is strong but not universal; a Prettier plugin for some exotic file type may not have a match.

The pragmatic pattern most teams land on is not “delete ESLint forever.” It is: run Biome for formatting and for every lint rule it covers — which is the overwhelming majority of what a normal project uses — and keep a thin ESLint config only for the specific plugin rules Biome has not reached yet. You still delete most of the stack; you just keep the one plugin you truly cannot live without.

Verdict: when to switch, when not to

Switch to Biome if you want your formatter and linter to be one fast, zero-config-drama tool, if your rule needs are covered by its built-in set, and if you are tired of maintaining the ESLint + Prettier plugin matrix. For a new project in 2026, reaching for Biome first is the sensible default — you get formatting, linting, and import sorting in one install, and CI that finishes before you have switched tabs.

Stay on ESLint — or run it alongside Biome — if your project leans on niche plugins or custom rules that Biome has not implemented yet. In that case use Biome for formatting and the rules it covers, and keep a minimal ESLint config for the rest. You still shed most of the weight.

The point is not to chase a new tool for its own sake. It is that formatting and linting stopped being a place where you should be spending afternoons on config and seconds on every CI run. Biome makes both of those close to free.

Terminal window
npm install --save-dev --save-exact @biomejs/biome
npx biome migrate eslint --write
npx biome migrate prettier --write
npx biome check --write .

Frequently asked questions

Is Biome really faster than ESLint and Prettier?

Yes, and the gap is large. Biome is written in Rust, runs as a single native binary, and parallelizes across cores, so it avoids the per-file Node.js and plugin overhead that ESLint and Prettier pay. In the official benchmarks published at biomejs.dev, formatting runs roughly 25x faster than Prettier, and linting runs around 20x faster than ESLint. On a real codebase that usually means a CI lint-and-format step drops from several seconds to a fraction of a second. Measure it on your own repository before you quote a number — the ratio holds, the absolute time depends on your code.

Can I migrate from ESLint and Prettier without rewriting my config?

Mostly, yes. Biome ships migration commands: `biome migrate eslint` and `biome migrate prettier` read your existing `.eslintrc` and `.prettierrc`, then translate the rules and formatting options into a `biome.json`. You will still want to review the result, because not every ESLint rule has a Biome equivalent, but the bulk of a standard setup converts automatically. Most teams get to a working `biome.json` in minutes rather than hours.

Does Biome support everything ESLint does?

No, and this is the honest limitation. ESLint has a huge plugin ecosystem with thousands of community and framework-specific rules, and Biome does not implement all of them. Biome covers the widely used correctness, style, and TypeScript rules plus framework rules for React and a11y, and the rule set grows every release, but if you depend on a niche plugin or a hand-written custom rule you may not find an equivalent yet. The common pattern is to run Biome for everything it covers and keep a thin ESLint config only for the rules it does not.

Is Biome production-ready?

Yes. Biome is the successor to the Rome project, is MIT-licensed, has a stable 1.x-and-beyond release line, ships an official VS Code extension and CI integrations, and is already used across many teams for formatting and linting. It has first-class support for JavaScript, TypeScript, JSX, JSON, and CSS, with more languages landing over time. For the vast majority of JavaScript and TypeScript projects the risk profile is comparable to Prettier plus ESLint, with far less configuration surface to maintain.

Does Biome work with Tailwind CSS and other frameworks?

Biome formats CSS directly and has a linter rule to sort Tailwind utility classes, so a lot of the Tailwind and framework workflow is covered natively. What it does not do is load arbitrary third-party formatting or linting plugins the way Prettier and ESLint do, so a few plugin-specific behaviours will not have a one-to-one match. For most React, Vue, and Tailwind projects Biome handles formatting and the core lint rules out of the box; check the rule list for the specific framework rules you rely on.

ENDE