ESLint is one of those tools that’s so deeply embedded in JavaScript development that most teams don’t think about it until something makes them notice it. Usually that something is CI time. You’re waiting for a lint step that takes three minutes on a codebase that should take three seconds, and you start to wonder whether there’s a better way.

There is. Oxlint is a linter built in Rust, developed by the Oxc project (the same people building a Rust-based JavaScript parser and bundler). It runs somewhere between 50 and 100 times faster than ESLint depending on your codebase size, ships with hundreds of built-in lint rules, and can be dropped into most projects with a single command.

What Makes It Fast

The short version: Rust and parallelism. Oxlint processes files concurrently across all available CPU cores, whereas ESLint’s plugin-based architecture runs synchronously by design — each plugin is a Node.js module that runs in a single thread.

On a large codebase with tens of thousands of files, that difference is dramatic. Oxlint’s own benchmarks show linting times of under one second on codebases that take two to three minutes in ESLint. Independent benchmarks from projects that have adopted it — including some large monorepos — report similar numbers.

The speed comes with a trade-off. Oxlint doesn’t support ESLint’s plugin system. You can’t install eslint-plugin-react or eslint-plugin-security and have Oxlint run those rules. The tool ships its own rule implementations for the most commonly used ESLint rules and selected plugin rules, but the long tail of community plugins isn’t available.

For most projects, the rules you actually rely on day-to-day are a much smaller set than the rules you have installed. Oxlint covers the high-value core.

Getting Started

Installation is a single command with no configuration required:

npx oxlint@latest

Run it in any JavaScript or TypeScript project and it’ll lint everything immediately. No config file, no plugin installation, no setup — it just works against a sensible default set of rules.

If you want to configure which rules run or adjust severity levels, you can create an oxlint.json file. The format is similar enough to ESLint’s configuration that it’s not a difficult transition:

{
  "rules": {
    "no-unused-vars": "error",
    "no-console": "warn"
  }
}

Oxlint supports TypeScript files natively — no separate parser plugin needed. It also handles JSX, Vue single-file components, and Astro files with the right extensions configured.

The Rule Coverage Question

This is the part worth going into carefully, because it’s where people get tripped up.

Oxlint implements rules from several rule sets: ESLint core, TypeScript-ESLint, eslint-plugin-react, eslint-plugin-unicorn, eslint-plugin-import, and a few others. The coverage isn’t complete — particularly for TypeScript rules that require type information, which Oxlint doesn’t yet support — but it covers a substantial portion of what most projects actually use.

The Oxc project publishes a rule table on their documentation site showing exactly which rules are implemented, which are in progress, and which aren’t planned. Before switching, it’s worth checking your existing .eslintrc against that table to see what gaps exist.

For teams running a lean ESLint config — maybe eslint:recommended plus TypeScript essentials plus a few React rules — the coverage is usually sufficient. For teams with a complex setup involving multiple custom plugins or heavy use of type-aware TypeScript rules, there’ll be gaps.

Most teams adopting Oxlint don’t rip out ESLint on day one. The recommended pattern is to run Oxlint first for speed, then run ESLint only for rules that Oxlint doesn’t cover:

{
  "scripts": {
    "lint": "oxlint && eslint --ext .ts,.tsx src/"
  }
}

You configure ESLint to disable all rules that Oxlint handles, so there’s no duplication. The combined runtime ends up significantly faster than ESLint alone because the expensive full-codebase scan is done by Oxlint, and ESLint only runs on a filtered set of files for the narrow set of rules it uniquely covers.

This is the approach taken by frameworks that have adopted Oxlint — including Vite and Vue — and it works well as a transitional strategy while Oxlint’s rule coverage expands.

Editor Integration

VS Code integration is available via the official Oxc extension in the marketplace. It provides real-time diagnostics as you type, with the same speed characteristics as the CLI — meaning suggestions appear without the noticeable lag that ESLint’s editor extension can produce on large files in complex projects.

The extension also shows which rules are firing and links to the rule documentation, which is what you’d expect from any decent linter integration.

JetBrains IDEs and Neovim are supported via the LSP protocol — the Oxc language server exposes the standard Language Server Protocol interface, so any editor that supports LSP gets diagnostics for free.

When to Adopt It

The clearest win is in CI pipelines where lint time is a visible bottleneck. If your lint step takes more than 30 seconds, Oxlint will meaningfully improve that. If your lint step takes five seconds, the improvement is still real but the practical impact on developer experience is smaller.

For local development, the speed difference matters most in large projects where ESLint on a full rebuild can take several seconds. In smaller projects, both tools are fast enough that the difference isn’t noticeable.

The migration cost is low enough that it’s worth trying even if you’re not sure. Install it, run it against your codebase, see what it flags, and compare the rule coverage to what you’re currently running. If the overlap is good enough for your project, the switch is essentially free. If there are gaps, the hybrid approach lets you keep the speed benefit while maintaining full coverage.

Oxlint is under active development and the rule set is expanding with each release. The trajectory is toward replacing ESLint entirely for most projects — but the hybrid approach means you can start capturing the speed gains now without waiting for that to happen.