← All posts

Biome vs Oxlint in 2026: Replacing ESLint

Rust-powered linters run 50–100× faster than ESLint, but choosing Biome or Oxlint depends on custom plugins, type-checking, and whether you want one tool instead of ESLint plus Prettier.

Contents

In brief

In 2026, many teams evaluate Biome and Oxlint as replacements for the ESLint + Prettier stack. Both are Rust binaries that traverse code tens of times faster than JavaScript tooling. Speed alone does not decide the winner: Biome unifies formatting and linting in one config, while Oxlint preserves ESLint plugins and incremental migration paths. The right pick depends on custom rules and how much TypeScript type information you need at lint time.

What happened

The JavaScript tooling layer hit a performance ceiling. ESLint with type-aware rules on a 50k LOC codebase can take 30–60 seconds; Prettier adds another 5–10. In monorepos with many packages, those delays multiply and linting becomes the pre-commit and CI bottleneck.

Biome (evolved from the Rome Tools idea) merges formatting and linting into one native binary. Two hundred-plus built-in rules cover correctness, style, and performance; many rules from eslint-plugin-react and eslint-plugin-import map directly. The hard limit: no custom plugins — internal rules for APIs, security, or frameworks block a Biome migration.

Oxlint, part of the Oxc project, maximizes ESLint compatibility while delivering extreme speed. Existing .eslintrc.json files and plugins like @typescript-eslint, react-hooks, and import work with minimal edits. Formatting stays on Prettier or similar. The Oxc parser builds an AST once and batches rule execution — hence ~2 seconds on 100k LOC versus minutes for ESLint.

The Dev.to comparison outlines four team profiles: proprietary ESLint plugins → Oxlint; full type-aware linting → Oxlint with TypeScript; toolchain consolidation → Biome; cautious incremental migration → Oxlint first, consolidate later.

Why it matters

When linting takes seconds instead of minutes, daily workflows change: save-on-type in the editor stops lagging, pre-commit hooks stop getting --no-verify, and CI can parallelize monorepo packages without a serial ESLint gate.

For TypeScript the tradeoff is sharper. ESLint with @typescript-eslint/recommended loads the full type graph — expensive but thorough. Biome uses fast-path analysis: common mistakes at full speed, but complex generics and conditional types can slip through. Oxlint can run true type-aware linting via the TypeScript compiler — 10–20× slower than bare Oxlint, still far faster than classic ESLint.

Criterion Biome Oxlint Classic ESLint
Speed Very high Highest Low on large codebases
Formatting Built in Separate tool Prettier separately
Custom plugins No Yes (compat layer) Yes
Type-aware Approximate Full (optional) Full
Migration Rewrite config Minimal edits

In practice

  1. Inventory — list .eslintrc rules and flag custom plugins. Any proprietary plugin rules out Biome for now.
  2. Pilot one package — swap eslint . for oxlint in package.json, or generate biome.json and drop duplicate Prettier/ESLint deps after validation.
  3. CI — Biome exposes biome ci (format + lint atomically); Oxlint needs separate oxlint and prettier --check steps that can disagree on edge cases.
  4. TypeScript-heavy codebases — if generics and conditional types are safety-critical, benchmark Oxlint with type-checking; if TS is mainly for editor hints, Biome may suffice.
  5. Greenfield — new repos without legacy plugins often start with Biome to avoid dual config drift.

Minimal starter biome.json:

{
  "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
  "formatter": { "enabled": true, "indentWidth": 2, "lineWidth": 100 },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" }
    }
  }
}

Takeaway

Rust rewrites of JavaScript tooling respond to an architectural limit of Node.js as an AST parser host. Biome and Oxlint are not direct competitors: one simplifies the stack, the other accelerates the ESLint world you already have. Before migrating, answer whether you need custom rules and full type-checking at lint time — that usually picks the tool for you.