Web Development · Tooling
Biome in 2026: One Tool to Replace ESLint and Prettier
Biome is a Rust-based JavaScript toolchain that handles linting, formatting, and imports in a single binary. We've been running it in production projects since late 2025. Here's what the migration from ESLint and Prettier actually looks like.
Anurag Verma
6 min read
Sponsored
JavaScript toolchain overhead is a well-documented frustration. ESLint has hundreds of rules, plugins that conflict with each other, configs that need to stay in sync between ESLint and Prettier, and startup times that make pre-commit hooks feel sluggish on large projects. Every team maintains their own version of the same eslint.config.js + .prettierrc setup, copied from a previous project and tweaked slightly.
Biome is a single binary written in Rust that does linting, formatting, and import organization. No plugins. No peer dependencies. No config file synchronization between two tools. On most projects, it’s 10-20x faster than ESLint + Prettier for equivalent checks.
We’ve been using it on client projects since late 2025. This is what the switch looks like.
What Biome Covers
Biome implements a substantial subset of the ESLint rule catalog, plus all of Prettier’s formatting behavior:
- Linting: 200+ rules across JavaScript, TypeScript, JSX, TSX, CSS, and JSON. Equivalent to ESLint recommended + a TypeScript plugin.
- Formatting: Prettier-compatible output. Files Biome formats should look identical to Prettier output (it passes ~97% of Prettier’s test suite).
- Import organization: Sorts and groups imports; replaces
eslint-plugin-importfor most use cases. - Safe fixes: Many lint errors have an auto-fix. Biome distinguishes “safe fixes” (semantically equivalent changes) from “unsafe fixes” (may change behavior) and lets you choose which to apply.
What it doesn’t cover yet: complex ESLint plugins like eslint-plugin-react-hooks, custom rules for your business logic, or deep TypeScript type-aware lint rules (those require type information Biome doesn’t currently use).
Installation
npm install --save-dev --save-exact @biomejs/biome
npx biome init
biome init creates a biome.json config file. For most projects, the defaults need minimal adjustment:
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"trailingCommas": "all",
"semicolons": "always"
}
},
"organizeImports": {
"enabled": true
}
}
Biome reads .gitignore for file exclusions (useIgnoreFile: true), so you don’t need to duplicate ignore patterns.
Basic Usage
# Check everything (lint + format check)
npx biome check .
# Check with auto-fix
npx biome check --write .
# Format only
npx biome format --write .
# Lint only
npx biome lint .
# Check a specific file
npx biome check src/components/Button.tsx
Output is clear and fast:
src/api/users.ts:23:5 lint/suspicious/noExplicitAny ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! Unexpected any. Specify a different type.
21 │ async function fetchUser(id: string) {
22 │ const response = await fetch(`/api/users/${id}`);
> 23 │ const data: any = await response.json();
│ ^^^
24 │ return data;
25 │ }
ℹ Avoid the any type, which bypasses the type checker.
Found 1 error(s) in 1 file(s) in 42ms
On a mid-size React + TypeScript project (300 files), Biome runs in under 500ms on first run, under 200ms on subsequent runs. ESLint + Prettier on the same project takes 8-12 seconds.
Performance Comparison
| Tool | 300-file TypeScript project | 1000-file project |
|---|---|---|
| ESLint + Prettier | ~10s | ~35s |
| Biome | ~400ms | ~1.2s |
| Biome (cached) | ~180ms | ~500ms |
Times vary by machine and rule set, but the difference is consistent. The gap matters most for pre-commit hooks and CI: a 10-second lint step in a commit hook creates friction that gets disabled. A 400ms check doesn’t.
Migrating From ESLint and Prettier
Biome includes a migration command:
npx biome migrate eslint --write
npx biome migrate prettier --write
These read your existing configs and convert what they can to biome.json. Not every ESLint rule has a Biome equivalent, so you’ll get a report of rules that couldn’t be migrated.
For most projects, the migration leaves you with Biome covering 80-90% of your previous rules. The remaining rules fall into three categories:
- Rules Biome already has under a different name: check the rules documentation.
- Plugin rules with no equivalent: evaluate if they’re actually catching bugs or just style preferences. Many plugin rules can be dropped without real impact.
- Custom rules: these need to stay in ESLint for now, or be rewritten as Biome plugins (the plugin API is still maturing).
For the transition period, you can run Biome and ESLint side by side: Biome for formatting and fast checks, ESLint only for the rules Biome doesn’t cover. This is less overhead than it sounds because ESLint’s startup time dominates, and running it over a smaller rule set is proportionally faster.
CI Integration
# .github/workflows/ci.yml
- name: Biome check
run: npx biome ci .
biome ci is the CI-specific command: it doesn’t write files, exits with a non-zero code on any error, and produces output suited for CI logs. It also skips the terminal color codes that CI systems sometimes mangle.
VSCode Extension
Install the Biome VSCode extension for inline diagnostics and format-on-save:
// .vscode/settings.json
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"[javascript][typescript][javascriptreact][typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
}
This replaces the Prettier and ESLint extensions for the file types Biome handles. For file types Biome doesn’t cover (Python, Markdown), the other extensions still work fine.
What We Kept in ESLint
After migrating four projects to Biome, we still run ESLint for two things:
eslint-plugin-react-hooks: The rules-of-hooks and exhaustive-deps rules catch a real class of React bugs. Biome doesn’t have these yet. We run this as a separate, focused ESLint check over React files only.
Type-aware rules: If you rely heavily on TypeScript-aware ESLint rules (like @typescript-eslint/no-floating-promises), those require type information that Biome currently doesn’t use. These rules are slower in ESLint too, so running them separately keeps your main check fast.
For non-React TypeScript projects with a standard ESLint config, Biome can replace the entire setup without gaps.
The Practical Case For Switching Now
Biome is not a prototype. Version 1.0 shipped in mid-2024, and the 1.x releases have been stable. The project is backed by a company (Biome Software) and has enough adoption that regression risks are caught quickly by the community.
The main reason to switch is developer experience. Fast lint checks are checks that run. Pre-commit hooks that take 10 seconds get disabled; hooks that take half a second stay on. The same principle applies to the CI step where a failing lint check is the fastest feedback loop you have.
For new projects, the question is whether to start with ESLint + Prettier or start with Biome. Given the current rule coverage and stability, Biome is the reasonable default unless you need React hooks rules or heavy TypeScript type-aware linting from day one. Even then, starting with Biome and adding a minimal ESLint config for those specific rules keeps the overhead low.
The configuration is simpler, the speed is genuinely better, and the migration path exists for when you want to move existing projects over.
Sponsored
More from this category
More from Web Development
CSS Anchor Positioning: Tooltips and Popovers Without JavaScript
gRPC in 2026: When to Use It Instead of REST or GraphQL
k6 Load Testing: Performance Testing Your APIs Before Users Find the Problems
Sponsored
The dispatch
Working notes from
the studio.
A short letter twice a month — what we shipped, what broke, and the AI tools earning their keep.
Discussion
Join the conversation.
Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.
Sponsored