Stopping the Config Drift: Consolidating Tooling with Biome
Stop fighting between Prettier and ESLint. Learn how Biome's unified Rust-based architecture eliminates config drift and accelerates linting and formatting in JS/TS projects.
20 Jun 2026, 01:20 UTC

The Friction of the 'Standard' Toolchain
Most modern JavaScript and TypeScript projects rely on a combination of Prettier for formatting and ESLint for linting. While powerful, this setup introduces a hidden tax: configuration drift. You end up managing a .prettierrc, an .eslintrc.js, and various ignore files. When a Prettier update changes how a trailing comma is handled, it might conflict with an ESLint rule, leading to a loop where the formatter fixes a file and the linter immediately flags it as an error.
In monorepos, this friction scales linearly. Managing consistent rules across twenty packages often means duplicating configs or fighting with complex extends chains in Node.js. The core problem isn't the rules themselves, but the overhead of maintaining two separate toolchains, two different plugin ecosystems, and two distinct execution engines.
A Unified Architecture in Rust
Biome solves this by consolidating formatting, linting, and import organization into a single binary written in Rust. Instead of running two separate processes that parse your code into two different Abstract Syntax Trees (ASTs), Biome parses the code once and applies all checks and transformations to that single tree.
This architectural decision eliminates the "fight" between the linter and formatter because they share the same logic and configuration file (biome.json). Because it is compiled Rust, the performance jump is significant. Formatting a large TypeScript monorepo that might take seconds in Node.js often completes in milliseconds with Biome, making it viable to run on every single file save without noticeable IDE lag.
Built-in Import Organization
One of the most practical wins in Biome is the integrated import sorter. Traditionally, teams added separate ESLint plugins to handle import ordering to prevent merge conflicts. Biome handles this natively, sorting imports by side-effect detection first, followed by external packages, and finally internal paths. This is handled as a "safe fix," meaning it can be automated in CI without risking logic changes.
Practical Implementation: From ESLint to Biome
Moving to Biome doesn't require manually recreating every rule. Biome provides a migration tool to bridge the gap from existing configurations.
Migration and Setup
To migrate an existing project, run the following command in your project root. This requires Node.js for the runner, though the core engine is a standalone binary.
# Run the migration tool to convert .eslintrc and .prettierrc to biome.json
npx @biomejs/biome migrate eslint --write
Risk: This is a one-way migration. Biome reads your old configs to generate a biome.json, but it cannot sync changes back to ESLint. Once you migrate, biome.json becomes your single source of truth.
Daily Workflow and CI
Once configured, you can replace your separate lint and format scripts with a single check command. Run these in your terminal or as part of a git pre-commit hook:
# Check for lint errors, formatting issues, and import order
npx @biomejs/biome check ./src
# Automatically apply safe fixes (formatting and simple lint fixes)
npx @biomejs/biome check --apply ./src
# Apply all fixes, including those that might change code behavior (use with caution)
npx @biomejs/biome check --apply-unsafe ./src
To verify the result, check your biome.json. You will see a unified structure where formatter and linter settings live side-by-side, removing the need for separate ignore files as Biome respects your .gitignore by default.
Trade-offs and Limitations
Biome is not a 1:1 replacement for every single ESLint plugin. Because Biome implements rules in Rust for performance, it does not support the JavaScript-based plugin ecosystem of ESLint.
- Plugin Gap: If your project relies on highly specialized plugins (e.g.,
eslint-plugin-jsx-a11yor specific React Hooks exhaustive-deps checks), you may find that Biome lacks a direct equivalent. In these cases, you might need to run a minimal ESLint config alongside Biome for those specific rules. - Opinionated Formatting: While Prettier is also opinionated, Biome's CSS and JSON formatting options are even more streamlined. If your team requires granular control over CSS property ordering, you may find Biome's defaults too rigid.
- Extensibility: You cannot write a custom lint rule in JavaScript for Biome. Adding new rules requires contributing to the Biome core in Rust.
Decision Matrix: Should you switch?
Switch to Biome if your primary goal is to reduce CI time, eliminate configuration drift, and simplify the onboarding process for new developers. It is particularly effective for monorepos where the overhead of multiple .eslintrc files becomes a maintenance burden. Keep ESLint only if you are deeply dependent on a niche plugin that has no equivalent in the Biome rule set.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.