Overview
Use Biome on new projects. It combines a linter and formatter into one fast tool, eliminates Prettier as a separate dependency, and requires no plugin config for standard JavaScript and TypeScript. Use ESLint when your project requires plugins without Biome equivalents: eslint-plugin-import, eslint-plugin-react-hooks, accessibility rules from eslint-plugin-jsx-a11y, or custom corporate rule sets. See swc-vs-babel for the adjacent build-tool decision.
When Biome wins
Biome is the right choice when the linting and formatting requirements are standard.
- Speed: Biome is written in Rust and runs lint and format in a single pass. On a 1000-file TypeScript project it typically completes in under 500 ms; ESLint with Prettier on the same project takes 5 to 15 seconds.
- Single tool: Biome replaces both ESLint and Prettier. One config file (
biome.json), one dev dependency, one CI step. - Zero config for TypeScript:
biome check .works out of the box on TypeScript, JSX, and JSON without plugins or parser overrides. - Consistent formatting: Biome’s formatter is intentionally Prettier-compatible for most cases, so a migration from Prettier produces minimal diffs.
- No plugin hell: ESLint v8 to v9 flat config migration broke many plugins. Biome has no equivalent fragility.
// biome.json
{
"linter": { "enabled": true, "rules": { "recommended": true } },
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
"javascript": { "formatter": { "quoteStyle": "double" } }
}When ESLint wins
ESLint is the right choice when plugin dependencies are real constraints.
eslint-plugin-react-hooks: enforces the Rules of Hooks. Biome’s React rule coverage is partial as of mid-2026; the hooks exhaustive-deps rule is not yet fully implemented.eslint-plugin-importandeslint-plugin-boundaries: graph-based import ordering and boundary enforcement. No Biome equivalent yet.eslint-plugin-jsx-a11y: accessibility linting for JSX. Critical for compliance-sensitive projects. Biome’s a11y rules cover some cases but not all.- Custom corporate rules: teams with internal
eslint-plugin-company-*packages have no migration path to Biome. - Framework-specific rule sets:
eslint-config-next,@angular-eslint, and Nx lint presets all target ESLint.
Running both Biome (for formatting) and ESLint (for rules) is a valid hybrid. Disable Biome’s linter and use it only for formatting, with ESLint handling rules.
Trade-offs at a glance
| Dimension | Biome | ESLint (with Prettier) |
|---|---|---|
| Speed | Very fast (Rust, single pass) | Slower; scales poorly past 500 files |
| Setup | One config file, zero plugins for basics | Multiple packages, possible parser conflicts |
| Formatting included | Yes | Only via Prettier integration |
| TypeScript support | Native | Via @typescript-eslint/parser |
| Plugin ecosystem | Growing; 200+ rules built in | Mature; thousands of plugins |
| React Hooks rules | Partial | Full via eslint-plugin-react-hooks |
| Accessibility rules | Partial | Full via eslint-plugin-jsx-a11y |
| Custom rules | Plugins in development | Rich custom rule authoring |
| Config migration (v9) | Not applicable | Flat config migration required for v9+ |
| Editor integration | VS Code extension, CLI | All editors; mature support |
Migration cost
ESLint plus Prettier to Biome is typically low-effort for standard configurations.
npx @biomejs/biome migrate eslint --writereadseslint.config.*or.eslintrc.*and generates an initialbiome.json. Handles common rule mappings automatically.- Run
biome check --apply .to auto-fix formatting and auto-fixable lint issues. Review the diff. - Disable Prettier and ESLint in CI. Remove
eslint,prettier, and related plugins frompackage.json. - Expect to lose some rules that have no Biome equivalent. Audit the ESLint rule list against the Biome rule reference before committing.
- Effort: half a day for a 200-file project with a standard config; longer if custom plugins are in use.
Recommendation
- New project with no special plugin requirements: Biome.
- New React project: Biome for formatting; add ESLint with
eslint-plugin-react-hooksfor hooks enforcement until Biome’s coverage is complete. - Existing ESLint project, standard rules: migrate when you have CI time to spare. The speed win is real.
- Existing ESLint project with custom plugins or strict a11y requirements: stay on ESLint.
- Hybrid: valid. Use
biome formatonly and ESLint for rules. Saves Prettier overhead without losing rule coverage.