Skip to main content

Guide

Biome vs ESLint vs Oxlint 2026: Which JS Linter to Pick

Oxlint is the fastest linter, Biome is the best all-in-one ESLint and Prettier replacement, and ESLint still wins on plugins. Compare 2026 tradeoffs.

·PkgPulse Team·
0
Hero image for Biome vs ESLint vs Oxlint 2026: Which JS Linter to Pick

Biome vs ESLint vs Oxlint: Which JS Linter Should You Use in 2026?

TL;DR

Choose ESLint when plugin coverage matters, choose Biome when you want one fast linter and formatter, and choose Oxlint when lint speed is the bottleneck. Oxlint is part of the OXC toolchain and is the fastest option in this comparison, but it is still best treated as a lint-only accelerator. Biome is the most practical ESLint + Prettier replacement for new projects. ESLint remains the safest default for mature React, Next.js, test-heavy, or security-sensitive codebases because the plugin ecosystem is still unmatched.

For the current search intent around Oxlint vs Biome, the short answer is: use Biome if you want linting, formatting, import organization, and simpler migration in one tool; use Oxlint if you already have formatting covered and want a very fast correctness/performance pass in CI. Use both only when lint feedback is a real bottleneck and you are comfortable keeping the responsibilities separate.

Key Takeaways

  • ESLint is still the ecosystem default. The eslint package recorded about 134M npm downloads for the week ending 2026-05-14, and @typescript-eslint/eslint-plugin recorded about 106M in the same npm window.
  • Biome has crossed into mainstream usage. @biomejs/biome recorded about 8.8M npm downloads for the week ending 2026-05-14, and Biome v2+ adds type-aware linting while keeping the formatter built in.
  • Oxlint is no longer niche. The oxlint package recorded about 6.7M npm downloads for the week ending 2026-05-14, and the OXC docs position it as a fast JavaScript and TypeScript linter.
  • Speed is not the only decision. Oxlint wins raw lint throughput; Biome wins the “replace ESLint + Prettier with one tool” job; ESLint wins when you need custom rules, framework plugins, or mature TypeScript lint coverage.
  • Avoid duplicate migrations. If you already plan to adopt Biome for formatting, do not add Oxlint just because it is faster. First decide whether Biome’s rules catch enough of your actual bugs.

Quick Decision Matrix

SituationBest pickWhy
New TypeScript app with standard React rulesBiomeOne config for lint, format, import organization, and fast local checks.
Existing Next.js app with eslint-plugin-next, React Hooks, a11y, testing, and import rulesESLintPlugin coverage and typed rule maturity matter more than raw speed.
Large monorepo where lint is a CI bottleneckOxlint + ESLintOxlint catches broad issues quickly, then ESLint runs the specialized rules you still need.
Team wants to remove Prettier and simplify configBiomeFormatter and linter ship together, so there is less tool coordination.
CLI package, scripts repo, or simple Node serviceOxlint or BiomeOxlint is excellent for fast lint-only checks; Biome is better if formatting is also in scope.
Codebase depends on custom internal ESLint rulesESLintBiome and Oxlint do not replace custom plugin behavior yet.

For a closer look at the OXC family, see OXC vs ESLint vs Biome: JavaScript Linting in 2026. For a narrower two-way migration guide, see How to Migrate from ESLint to Biome and Oxlint Migration Guide from ESLint for React Projects.


What Each Tool Is Optimizing For

ESLint: maximum rule and plugin coverage

ESLint is a pluggable JavaScript linter. Its core strength is not just the built-in rules; it is the surrounding ecosystem of framework, accessibility, import, testing, security, React Hooks, and custom organization-specific plugins. That ecosystem is why ESLint remains the default recommendation for mature product codebases even as Rust-based tools get much faster.

The configuration model has also changed. ESLint’s modern flat config uses eslint.config.js rather than the older cascading .eslintrc.* system. That matters for monorepos: flat config makes rule application more explicit and avoids many “which config file applied here?” debugging sessions.

// eslint.config.js
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import reactHooks from "eslint-plugin-react-hooks";

export default [
  js.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    files: ["**/*.{ts,tsx}"],
    plugins: {
      "react-hooks": reactHooks,
    },
    rules: {
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": "warn",
      "@typescript-eslint/no-floating-promises": "error",
    },
  },
];

Choose ESLint when:

  • your codebase relies on Next.js, React Hooks, testing-library, Playwright, Storybook, import, security, or custom internal rules;
  • you need mature type-checked TypeScript rules from @typescript-eslint;
  • the migration risk of losing rule coverage is higher than the lint-time savings;
  • your team already has well-understood ESLint conventions.

Do not choose ESLint just because it is familiar if the project is greenfield, the rule set is generic, and formatting plus linting can be handled by one simpler tool.

Biome: the all-in-one ESLint and Prettier replacement

Biome is the best fit when the actual problem is tool sprawl. It combines linting, formatting, import organization, and configuration into one Rust-based toolchain. The Biome homepage describes it as a web toolchain, and the Biome linter docs now include the v2-era capabilities that made teams revisit migrations that were too risky in 2024 or 2025.

// biome.json
{
  "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
  "organizeImports": { "enabled": true },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" },
      "suspicious": { "noExplicitAny": "warn" },
      "style": { "useConst": "error" }
    }
  }
}

Biome’s biggest advantage over Oxlint is scope. Oxlint is a linter; Biome is a linter plus formatter. If your current developer workflow runs ESLint, Prettier, import sorting, and editor format-on-save separately, Biome can remove several moving parts at once.

Choose Biome when:

  • you are starting a new app and want one fast default tool;
  • you want to replace both ESLint and Prettier, not just speed up linting;
  • your current ESLint config mostly uses common correctness, style, and suspicious-code rules;
  • your team values editor latency and simple pre-commit hooks.

Keep ESLint next to Biome when:

  • React Hooks dependency checking is non-negotiable;
  • Next.js, testing, a11y, import-cycle, or custom plugin rules still catch production-relevant bugs;
  • a rule parity audit shows gaps you are not willing to accept.

Oxlint: fastest lint-only pass from the OXC toolchain

Oxlint is the linter in the OXC project. The OXC docs position it as a fast JavaScript and TypeScript linter, and the package’s npm download growth shows that teams are now using it beyond experiments. The tradeoff is that Oxlint is intentionally narrower than Biome and ESLint: it does not try to be your formatter, and it does not have ESLint’s plugin ecosystem.

# Fast broad lint pass
bunx oxlint .

# Use stricter categories in CI
bunx oxlint --deny correctness --deny suspicious .

# Pair with the remaining ESLint rules that Oxlint cannot replace
bunx oxlint . && bunx eslint . --cache

The strongest Oxlint pattern is a CI pre-pass. Put Oxlint before ESLint so obvious correctness and performance issues fail quickly, then keep ESLint for specialized rules. This is especially useful in monorepos where a full ESLint run is slow but still necessary.

Choose Oxlint when:

  • raw lint speed is the highest-priority issue;
  • you want a low-risk pre-pass before ESLint;
  • your project is simple enough that broad correctness rules are enough;
  • you already use Prettier or another formatter and do not need Biome’s formatting layer.

Do not choose Oxlint as a full ESLint replacement until you have confirmed that the rules you depend on are covered and that limited auto-fix support is acceptable for your workflow.


Biome vs Oxlint: The Real Choice

Most searchers comparing Biome vs Oxlint are deciding between two Rust-based tools, but they solve different jobs.

Biome is a workflow replacement. It can take over formatting, many ESLint-style rules, import organization, and editor feedback. A team can standardize on biome check --write . locally and biome ci . in CI.

Oxlint is a lint accelerator. It is especially attractive when a large repo already has ESLint and Prettier configured, but the ESLint run is too slow. In that case, Oxlint can catch many mistakes almost instantly while ESLint remains the authority for framework-specific and typed rules.

A practical rule:

  • If you are willing to change formatting, use Biome first.
  • If you are not willing to change formatting and only need speed, evaluate Oxlint first.
  • If you need plugin depth, keep ESLint in the loop either way.

ESLint vs Biome vs Oxlint Feature Table

DimensionESLintBiomeOxlint
Latest npm version checked10.4.02.4.151.65.0
Npm downloads, week ending 2026-05-14~134M~8.8M~6.7M
Primary rolePluggable linterLinter + formatter toolchainFast lint-only pass
FormattingNo; usually paired with PrettierYesNo
Import organizationVia plugins/configBuilt inLimited compared with dedicated import tools
TypeScript supportMature via @typescript-eslintBuilt-in parser and v2+ type-aware linting directionTypeScript syntax support; narrower typed-rule story
Framework pluginsStrongLimitedLimited
Custom rulesStrongNot an ESLint plugin replacementNot an ESLint plugin replacement
Auto-fix maturityStrongStrong for covered rules/formattingImproving but narrower
Best migration styleKeep unless rule coverage is the bottleneckReplace ESLint + Prettier after a rule auditAdd before ESLint, then reduce ESLint only where safe

Download data above is from the npm downloads API for 2026-05-08 through 2026-05-14. Docs/source pages checked on 2026-05-15: Biome homepage and linter docs, Biome v2 release notes, ESLint homepage and flat config docs, and OXC Oxlint usage/rules docs.


Migration Playbooks

If you are on ESLint + Prettier today

Start with a rule audit, not a speed benchmark.

  1. List every plugin and custom rule in your current ESLint config.
  2. Categorize each rule as covered by Biome, covered by Oxlint, still ESLint-only, or no longer needed.
  3. Decide whether formatting can move from Prettier to Biome.
  4. If formatting can move, test Biome on a branch and keep a minimal ESLint config for the gaps.
  5. If formatting cannot move, test Oxlint as a pre-pass and keep ESLint as the authority.
# Biome branch test
bun add -d @biomejs/biome
bunx biome init
bunx biome migrate eslint --include-inspired
bunx biome check .

# Oxlint branch test
bun add -d oxlint
bunx oxlint .
bunx eslint . --cache

Keep the formatting commit separate if you adopt Biome. Bulk formatting makes review noisy, so commit it alone and add the formatting commit to .git-blame-ignore-revs if the team uses blame heavily.

If you are starting a new project

Start with Biome unless you already know you need ESLint plugins. For many new TypeScript apps, that gives the best developer experience: fast editor feedback, one config file, one CI command, and no Prettier coordination.

Add ESLint only for specific gaps. The common example is React Hooks or framework-specific checks that your team considers production-critical. Keeping ESLint small is the point: Biome should handle the broad formatting and general lint layer.

If you have a large monorepo

Use a staged pipeline:

# Fast failure for broad issues
bunx oxlint .

# Formatter/linter authority if you use Biome
bunx biome ci .

# Specialized rules that still require ESLint
bunx eslint . --cache --max-warnings=0

Do not run all three forever by default. Measure which checks catch unique issues. If Oxlint and Biome overlap too much for your repo, remove one. If ESLint is only catching React Hooks and Next.js rules, shrink the ESLint config to those rules and keep the faster tool for the general layer.


Rule Coverage Questions to Ask Before Switching

Before replacing ESLint, answer these questions with your actual config open:

  • Do you use react-hooks/exhaustive-deps, eslint-plugin-next, eslint-plugin-jsx-a11y, eslint-plugin-import, testing-library, Playwright, Storybook, or security plugins?
  • Do you rely on type-aware rules such as no-floating-promises, strict boolean checks, or promise misuse detection?
  • Do you have custom internal rules that enforce product-specific conventions?
  • Are formatter diffs acceptable in one dedicated migration commit?
  • Does the editor extension story work for every language and file type your team edits?
  • Can CI run a trial mode for a week and compare unique findings before the switch?

If most answers point to plugin-heavy coverage, keep ESLint and add Oxlint only if speed hurts. If most answers point to simple style/correctness rules plus Prettier, Biome is likely the better target.


Final Recommendation

For most teams in 2026:

  1. Default to ESLint for mature apps with plugin-heavy rules. It is slower, but the ecosystem coverage is still the reason it exists.
  2. Use Biome for new apps and for teams ready to replace both ESLint and Prettier. It gives the cleanest everyday developer workflow when rule coverage is sufficient.
  3. Use Oxlint as a speed layer, not a full governance layer. It is the best answer when the query is “how do we make lint feedback nearly instant?” rather than “how do we replace our full JavaScript quality stack?”

The highest-confidence migration is not a big-bang replacement. Run the candidate tool beside your current lint workflow, compare unique findings, then remove redundant checks. That turns Biome vs ESLint vs Oxlint from a tooling debate into an evidence-backed cleanup: keep the deepest rule coverage, remove duplicate work, and make the fast path the default.

Sources Checked

  • Biome homepage and linter docs — accessed 2026-05-15: https://biomejs.dev/, https://biomejs.dev/linter/
  • Biome v2 release notes — accessed 2026-05-15: https://biomejs.dev/blog/biome-v2/
  • ESLint homepage and flat config docs — accessed 2026-05-15: https://eslint.org/, https://eslint.org/docs/latest/use/configure/configuration-files
  • OXC Oxlint usage and rules docs — accessed 2026-05-15: https://oxc.rs/docs/guide/usage/linter.html, https://oxc.rs/docs/guide/usage/linter/rules.html
  • npm downloads API package snapshots for eslint, @typescript-eslint/eslint-plugin, @biomejs/biome, and oxlint — queried 2026-05-15 for the 2026-05-08 through 2026-05-14 window

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.