Linting is one of those tasks that everyone agrees is worth doing and nobody enjoys waiting for. On a big codebase, ESLint can turn a pre-commit hook into a coffee break and a CI step into a real chunk of your build budget. Oxlint takes a different approach: written in Rust, multi-threaded, and shipped with hundreds of rules built straight in, it lints JavaScript and TypeScript fast enough that you stop noticing it happens at all.
Oxlint is part of the broader Oxc toolchain (the "Oxidation Compiler"), a family of high-performance JavaScript and TypeScript tools backed by VoidZero, the same company behind Vite and Rolldown. It reached its 1.0 stable release in June 2025 after more than 200 contributors put in roughly eighteen months of work, and it now pulls in well over eight million weekly downloads. In other words, this is not a weekend experiment. It is a production-grade tool that a lot of teams already lean on every day.
Why Anyone Bothers Switching Linters
The headline number is the one everyone quotes: Oxlint is marketed as 50 to 100 times faster than ESLint. That sounds like marketing until you understand where it comes from. ESLint runs on a single thread; Oxlint spreads its work across all your CPU cores, so the speedup actually scales with your hardware. Real-world migrations back this up, with reports ranging from a roughly 5x improvement on the Node.js project to 16x and beyond on large codebases that lean heavily on plugins.
When linting drops from minutes to seconds, the way you use it changes. You can run it on every file save, wire it into a lint-staged pre-commit hook without anyone complaining, and stop treating it as a CI bottleneck. Beyond raw speed, a few things make Oxlint pleasant to adopt:
- 800+ built-in rules with no plugins to install, including ports of ESLint core, typescript-eslint, eslint-plugin-react, react-hooks, jsx-a11y, eslint-plugin-import, unicorn, Jest, and Vitest.
- Zero-config defaults that work out of the box, focused on the
correctnesscategory so the noise stays low. - Type-aware linting for rules like
no-floating-promisesthat previously required typescript-eslint. - A migration path that lets Oxlint and ESLint coexist while you transition, rather than forcing a risky big-bang rewrite.
Getting It Onto Your Machine
You can try Oxlint without installing anything, which is the fastest way to see what it flags in your project.
# Run it once, no install required
npx oxlint@latest
When you are ready to make it part of the project, add it as a dev dependency.
# npm
npm add -D oxlint
# yarn
yarn add -D oxlint
Then wire up a couple of scripts in your package.json.
{
"scripts": {
"lint": "oxlint",
"lint:fix": "oxlint --fix"
}
}
That is genuinely all the setup it takes. There is no required config file, no plugin install, and no flat-config ritual to perform before the first run.
The First Run
Running Oxlint against the current directory needs nothing more than the command itself.
oxlint
By default it walks your project, respects your .gitignore, and applies its sensible defaults. It mostly runs rules in the correctness category, which are the ones that catch real bugs rather than stylistic preferences, so the output tends to be short and worth reading.
When you want Oxlint to clean up after itself, add the --fix flag. It applies only the fixes it considers safe, so you can run it without holding your breath.
oxlint --fix
It handles the file types you would expect, including .js, .mjs, .cjs, .ts, .mts, .cts, .jsx, and .tsx. It also reads the script blocks inside .vue, .svelte, and .astro files, though full template linting for those frameworks is still limited.
Telling Oxlint What You Want
When the defaults are not quite enough, Oxlint reads a JSON config file named .oxlintrc.json. The structure will feel familiar if you have ever touched an ESLint config: you set rule severities, toggle whole categories, and define ignore patterns.
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"categories": {
"correctness": "error",
"suspicious": "warn"
},
"rules": {
"no-console": "warn",
"no-debugger": "error"
},
"ignorePatterns": ["dist/**", "build/**", "coverage/**"]
}
Categories are the coarse dial and individual rules are the fine one. You can switch on a broad category like suspicious and then override specific rules underneath it. Rules are organized into correctness, suspicious, pedantic, style, restriction, and nursery, which gives you a clean way to dial strictness up or down for a whole class of checks at once.
For the times when a rule is wrong about one specific line, inline comments work just like you would hope.
// oxlint-disable-next-line no-console
console.log("This one is intentional, I promise.");
Oxlint also supports nested configs, so a monorepo can have a base .oxlintrc.json at the root and more specific overrides inside individual packages. Each subdirectory inherits and extends the configuration above it, which keeps per-package tweaks local instead of bloating one giant file.
Catching Bugs the Type Checker Knows About
For a long time the biggest gap between Oxlint and typescript-eslint was type-aware rules, the kind that need a real type checker to work. Things like no-floating-promises cannot be decided by looking at a single file in isolation; they need to understand the types flowing through your program. Oxlint now handles these through a two-binary design: the Rust oxlint CLI does file traversal and the non-type-aware rules, while a companion binary called tsgolint uses the native Go port of the TypeScript compiler to run the type-aware checks.
To turn it on, install the companion package and pass the flag.
npm add -D oxlint oxlint-tsgolint@latest
npx oxlint --type-aware
That unlocks around 43 type-aware rules, including no-floating-promises, no-misused-promises, await-thenable, no-deprecated, and strict-boolean-expressions. Because it leans on the actual Go-based TypeScript compiler rather than a partial reimplementation, the type-system behavior matches what tsc would tell you. And it stays fast: benchmarks put it at roughly 10x quicker than ESLint plus typescript-eslint, with the Vue core repository finishing in about 2.5 seconds versus 20.8. Worth knowing that type-aware linting is still in alpha as of mid-2026, so treat it as promising rather than rock-solid for mission-critical pipelines.
Migrating Without Burning the Bridge
The smart way to adopt Oxlint is not to rip out ESLint on day one. The recommended pattern is to run Oxlint first because it is fast and catches most issues, then run ESLint afterward only for the rules Oxlint does not cover yet. To stop the two tools from flagging the same problems twice, there is an eslint-plugin-oxlint that disables the ESLint rules Oxlint already handles.
Start by converting your existing ESLint config with the official migration tool.
npx @oxlint/migrate
That generates a .oxlintrc.json from your current setup. Then layer the deduplication plugin into your ESLint flat config so ESLint quietly steps aside for anything Oxlint owns.
// eslint.config.js
import oxlint from "eslint-plugin-oxlint";
export default [
// ...your existing ESLint config
...oxlint.configs["flat/recommended"],
];
Your scripts then run them in sequence, fast tool first.
{
"scripts": {
"lint": "oxlint && eslint ."
}
}
As Oxlint's coverage grows, you keep shifting more work to it and shrinking the ESLint step. A recent development on that front is JS Plugins, an alpha ESLint-compatible plugin API that lets Oxlint run many existing ESLint plugins unmodified and lets you author custom rules in JavaScript or TypeScript. It uses an optimized Rust-to-JavaScript bridge to keep the heavy lifting on the Rust side, and the maintainers estimate it lets roughly 80 percent of ESLint users switch and have things "just work." Custom framework support such as Vue and Svelte is still maturing, so check your specific plugins before counting on a full cutover.
How It Stacks Up
The obvious comparison is ESLint itself, which still wins on raw ecosystem breadth, flat-config flexibility, and a fully mature type-aware story through typescript-eslint. What it cannot match is speed, and Oxlint is steadily closing the feature gap on the other fronts.
The other Rust-based contender is Biome, which bundles linting and formatting into one fast tool. The key differentiator is that Biome does not do full type-aware linting, because it has no real type-checker integration, while Oxlint's tsgolint gives it genuine type-aware rules backed by the actual TypeScript compiler. Oxc splits formatting into a separate tool called Oxfmt, so if you want a single all-in-one binary Biome may suit you better, and if true type-aware linting matters more, Oxlint pulls ahead.
Should You Make the Jump
Oxlint has crossed the line from interesting newcomer to serious option. The 1.0 release, the millions of weekly downloads, and the backing of the team behind Vite all point to something built to last rather than a flashy demo. The two historical objections, no type-aware rules and no ESLint plugin support, are both being answered, even if those answers are still wearing their alpha labels.
The lowest-risk move is to add it alongside ESLint today and feel the speed difference immediately, using eslint-plugin-oxlint to keep things tidy. From there you can let Oxlint take over more of the work at whatever pace your team is comfortable with. Either way, the days of waiting on a linter to finish are looking numbered, and that is a very pleasant problem to have.