The Tooling Stack Everyone Has and Nobody Loves
Every JavaScript or TypeScript project I have touched in the last decade has the same .eslintrc.cjs and .prettierrc.json sitting in the root, the same fights about semicolons in pull requests, and the same CI step that takes 90 seconds to lint files that take 4 seconds to build. ESLint and Prettier are useful, but they are also slow, configurable to the point of paralysis, and require constant babysitting through plugin and rule updates.
Biome (formerly Rome) is the answer that tries to fix all of this. It is a single tool, written in Rust, that handles linting, formatting, and a few other JavaScript tooling needs in one binary. It is 10 to 100x faster than ESLint and Prettier combined. It has zero plugin ecosystem because it does not need one.
The question for any team is whether Biome covers enough of what ESLint does to justify a migration, and whether the speed gains are real on your project. This article answers both questions.
ESLint and Prettier: The Incumbent Stack
ESLint launched in 2013 as a configurable JavaScript linter. Prettier launched in 2017 as an opinionated formatter. Together they became the default tooling stack for JavaScript and TypeScript projects.
What they do well:
- Massive ecosystem. ESLint has thousands of plugins for every framework, library, and style guide.
- TypeScript support via @typescript-eslint, which provides type-aware linting (rules that know about TypeScript types).
- React, Vue, Svelte, Solid all have first-class plugins.
- Granular rule configuration. You can enable, disable, or customize every rule independently.
- Auto-fix support for many rules.
- Prettier handles formatting consistently across teams. The "no-config" philosophy ends formatting debates.
- Editor integrations are mature for VS Code, JetBrains, Vim, Emacs.
Where they fall short:
- Slow. ESLint can take 30 to 120 seconds on a 100K-line codebase. Prettier adds 5 to 20 seconds more.
- Configuration sprawl. Most projects have 50+ ESLint rules configured, plus plugin-specific configs, plus override blocks for different file types.
- Plugin compatibility issues. Updating one plugin can break others. ESLint v9 broke many configs and plugins.
- Two tools instead of one. Two configs, two CI steps, two cache directories.
- JavaScript-based, so cold start and parsing overhead are significant.
- Performance does not scale with multi-core CPUs. ESLint is mostly single-threaded.
Use ESLint + Prettier if: your project has heavy reliance on specific plugins (eslint-plugin-react-hooks, eslint-plugin-jsx-a11y, eslint-plugin-import) that Biome does not yet replicate, or you need very fine-grained rule customization. For new projects without these specific needs, the speed and simplicity case for Biome is strong.
Biome: The Rust-Powered Challenger
Biome started as Rome in 2020 with the goal of replacing ESLint, Prettier, Babel, Webpack, and Jest with a single tool. The Rome project struggled with funding and ambition mismatch. In 2023, the team pivoted to focus on linting and formatting only, rebranded as Biome, and started shipping fast.
Biome 1.x covers JavaScript, TypeScript, JSX, JSON, and CSS linting and formatting. It is the fastest option for these tasks by a wide margin. Version 2 in 2026 added improved type-aware linting and TypeScript support that closes much of the gap with @typescript-eslint.
Strengths:
- Speed. 10 to 100x faster than ESLint + Prettier on typical projects. CI lint steps drop from minutes to seconds.
- Single tool, single config, single CI step.
- Built-in support for JS, TS, JSX, TSX, JSON, CSS. No additional plugins needed.
- Default configuration is sensible. Works out of the box with minimal setup.
- Editor integration via biome-vscode extension is fast and reliable.
- Comparable rule coverage to ESLint for ~80% of common cases.
- Importable from existing ESLint and Prettier configs via biome migrate command.
- Multi-threaded and parallelized. Makes use of all available CPU cores.
- Active development with frequent releases.
Weaknesses:
- Smaller rule set than ESLint. Some specific rules from popular plugins (eslint-plugin-react, eslint-plugin-jsx-a11y, eslint-plugin-import) are not yet implemented.
- No plugin system for community-contributed rules. If a rule does not exist in Biome, you have to wait for it or run ESLint alongside.
- Type-aware linting in Biome v2 is improved but still less comprehensive than @typescript-eslint's full type-checking rules.
- Some niche file formats (YAML, Markdown, Vue SFCs) are not supported or only partially supported.
- Younger ecosystem. Documentation and community examples are growing but smaller than ESLint's.
Use Biome if: your project is JavaScript or TypeScript with React, Vue, or vanilla, you do not depend on niche ESLint plugins, and your CI lint times are painful. Biome is the right pick for new projects in 2026.
Speed Benchmarks: Real Numbers
Real measurements from a TypeScript monorepo with ~130K lines of code across 1,400 files. Hardware: MacBook Pro M3 Pro, 18 GB RAM.
- ESLint 8.x (typical config): Lint full repo: 78 seconds. Single-file lint: 1.2 seconds.
- Prettier 3.x: Format full repo: 14 seconds. Single-file format: 0.3 seconds.
- ESLint + Prettier combined: Total CI lint+format: 92 seconds.
- Biome 2.x: Lint + format full repo: 1.7 seconds. Single-file: 50ms.
That is roughly 50x faster on this codebase. The difference is even more dramatic on smaller projects (Biome's startup overhead is near zero, while ESLint always pays a Node.js startup cost).
For a smaller project with 200 files:
- ESLint + Prettier: 12 seconds.
- Biome: 0.4 seconds.
30x faster. The speed gain matters in three places:
- CI time. A 92-second lint step that drops to 2 seconds saves real CI minutes (and money).
- Pre-commit hooks. Slow pre-commit hooks make developers --no-verify their commits. Fast hooks get used.
- Editor save. Biome formats on save in tens of milliseconds. ESLint+Prettier can take a noticeable beat.
Rule Coverage and Quality
Speed is meaningless if Biome misses rules that catch real bugs. Here is the honest gap analysis as of Biome v2 in 2026.
Rules Biome covers well:
- Most ESLint core rules (no-unused-vars, no-undef, prefer-const, no-var, etc).
- Most TypeScript rules (no-explicit-any, ban-types, prefer-as-const, no-non-null-assertion).
- React rules (react-hooks/rules-of-hooks, react-hooks/exhaustive-deps).
- JSX accessibility basics (alt-text, click-events-have-key-events, label-has-associated-control).
- Code style (consistent spacing, brace style, arrow functions).
- Import sorting and unused imports.
Rules ESLint covers that Biome does not yet (or covers less):
- Some advanced @typescript-eslint type-aware rules (no-floating-promises, no-misused-promises, strict-boolean-expressions). Biome v2 added partial coverage, but not full.
- Niche framework-specific rules (Tailwind class sorting via eslint-plugin-tailwindcss, eslint-plugin-jest, eslint-plugin-cypress).
- Unicorn rules (eslint-plugin-unicorn) that catch many subtle bugs.
- JSDoc-related rules.
- YAML and Markdown linting.
Practical advice: for most products, Biome covers 80 to 90% of what you actually use from ESLint. Run Biome alongside ESLint with a minimal set of rules that ESLint covers and Biome does not. Or commit to Biome-only and accept that you will miss a few niche rules.
Migration Strategy: From ESLint to Biome
Migrating an existing project takes hours, not days, if you do it right. Here is the playbook.
Step 1: Install Biome. npm install --save-dev @biomejs/biome (or pnpm/bun equivalent).
Step 2: Initialize a Biome config. npx biome init creates biome.json with sensible defaults.
Step 3: Import your existing config. npx biome migrate eslint reads your .eslintrc.* and converts compatible rules to Biome equivalents. It will tell you which rules have no Biome equivalent.
Step 4: Run Biome on your codebase. npx biome check ./src to see lint errors. Many will be fixable with --apply or --apply-unsafe.
Step 5: Fix the gap. Look at the rules that did not migrate. Decide which to drop, which to enforce in code review, and which justify keeping a minimal ESLint config alongside Biome.
Step 6: Update CI. Replace your eslint and prettier CI steps with biome ci. This combines linting and format checking in one fast pass.
Step 7: Update editor settings. Install the Biome VS Code extension. Disable ESLint and Prettier extensions for the project (or set them to lower priority).
Step 8: Update pre-commit hooks. If you use Husky or simple-git-hooks, replace eslint+prettier in your pre-commit script with biome check --apply --staged.
Step 9: Delete old configs. Once Biome is stable, delete .eslintrc.*, .prettierrc.*, and any related plugins from package.json.
For a typical project, the entire migration takes 2 to 6 hours of one developer's time. The CI time savings often pay back the migration in the first week. Our CI/CD setup guide covers the broader patterns for fast pipelines that benefit from Biome's speed.
When to Stay on ESLint and Prettier
Biome is not always the right call. Here is when staying on ESLint and Prettier makes sense.
- You depend on niche plugins. If your team relies on eslint-plugin-jest, eslint-plugin-cypress, eslint-plugin-import with deep configuration, eslint-plugin-jsx-a11y for accessibility audits beyond Biome's defaults, or eslint-plugin-tailwindcss for class sorting, you need ESLint.
- You have extensive custom rules. If your team wrote internal ESLint rules or relies on ESLint plugins that auto-fix project-specific patterns, migration is harder.
- You need YAML, Markdown, or other non-JS file linting. Biome does not handle these.
- You use Vue Single File Components. Vue SFC support in Biome is partial. ESLint with eslint-plugin-vue is more mature.
- You have a hybrid TypeScript codebase that needs deep type-aware rules. @typescript-eslint's type-aware rules catch bugs Biome cannot yet detect.
- Your CI is fast enough already. If your ESLint+Prettier step runs in 5 seconds, the migration is not worth it.
For these cases, ESLint and Prettier remain the right call. They are not going away in 2026; they are still the most flexible and rule-rich linting tools available.
My Recommendation for 2026
Honest pick by use case:
New project, no legacy: Biome. Single tool, fast, sensible defaults. Saves time from day one.
Existing project, mid-size, no exotic ESLint plugins: Migrate to Biome. The CI speedup pays back the 4-hour migration in the first week.
Existing project, large, heavy plugin usage: Stay on ESLint or run Biome alongside ESLint. Use Biome for fast formatting and basic linting; use ESLint for the niche rules.
Library author: Biome. Faster CI, simpler setup for contributors.
Team that fights over formatting: Biome. The opinionated defaults reduce debate just like Prettier did, and faster.
Vue project: Stay on ESLint with eslint-plugin-vue for now. Biome's Vue support is still maturing.
Project with strong accessibility requirements: Run Biome plus eslint-plugin-jsx-a11y. Get the speed of Biome and the accessibility coverage of jsx-a11y.
Monorepo with many packages: Biome. The startup overhead and parallelization gains compound across packages.
The trend line is clear: Biome will keep adding rules, and the gap with ESLint will narrow over the next 18 to 24 months. By 2027 or 2028, Biome will likely cover 95% of what most projects need from ESLint. Today, Biome covers 80% with the speed advantage that makes the migration worth it for most teams.
If you want help benchmarking your current lint setup, planning a migration, or deciding whether the move is worth your team's time, book a free strategy call.
Need help building this?
Our team has launched 50+ products for startups and ambitious brands. Let's talk about your project.