Oxlint
Explore Ultracite's Oxlint and Oxfmt setup for teams that prioritize lint speed, shared presets, and lightweight editor defaults.
Oxlint is part of the Oxc project, a collection of high-performance JavaScript tools written in Rust. Paired with Oxfmt for formatting, this toolchain is ideal for large codebases where speed is critical.
Benefits
- 50-100x faster — Lint your entire codebase in milliseconds
- 15 plugin equivalents — Built-in support for React, TypeScript, Next.js, Vue, Jest, Vitest, and more
- Bug-focused rules — Prioritizes catching real bugs over stylistic issues
- High signal-to-noise ratio — Fewer false positives, more actionable feedback
- Oxc ecosystem — Part of a larger project with parser, resolver, transformer, and minifier
- Drop-in ready — Works alongside existing setups or as a complete replacement
Usage
Ultracite generates two TypeScript config files for Oxlint:
import { defineConfig } from "oxlint";
import core from "ultracite/oxlint/core";
export default defineConfig({
extends: [core],
ignorePatterns: core.ignorePatterns,
});
import { defineConfig } from "oxfmt";
import ultracite from "ultracite/oxfmt";
export default defineConfig({
...ultracite,
});
Add framework presets as needed:
import { defineConfig } from "oxlint";
import core from "ultracite/oxlint/core";
import next from "ultracite/oxlint/next";
import react from "ultracite/oxlint/react";
export default defineConfig({
extends: [core, react, next],
ignorePatterns: core.ignorePatterns,
});
ESLint Parity (Optional)
The core preset — and the react, next, and tanstack framework presets — run entirely on Oxlint’s native, Rust-powered rules for maximum speed. If you want to close the remaining gap with the ESLint preset, Ultracite ships an opt-in js-plugins preset that runs eslint-plugin-github, eslint-plugin-sonarjs, and oxlint-plugin-react-doctor through Oxlint’s JS plugin support.
This is off by default because it adds dependencies and runs a slower JavaScript lint pass instead of the native Rust one. You can enable it during setup: interactive ultracite init lets you choose individual JS plugins when you choose Oxlint, and non-interactive setup accepts package names via --js-plugins.
npx ultracite init --linter oxlint --js-plugins eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctorpnpm dlx ultracite init --linter oxlint --js-plugins eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctoryarn dlx ultracite init --linter oxlint --js-plugins eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctorbunx ultracite init --linter oxlint --js-plugins eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctorNote: The React Doctor rules used to be bundled into the
react,next, andtanstackpresets. They now live injs-pluginsso those framework presets stay on the fast native path. Extendjs-pluginsalongside your framework preset to keep them.
React Doctor’s framework-specific rules are split into per-framework add-on presets so they only run where they apply — nextjs-* rules like nextjs-no-img-element fire on plain <img>/<a> JSX and would false-positive in non-Next.js apps. init wires these up automatically when you pick the matching framework together with oxlint-plugin-react-doctor:
ultracite/oxlint/next/js-plugins— React Doctor’s Next.js rulesultracite/oxlint/tanstack/js-plugins— React Doctor’s TanStack Query/Router/Start rules
If you’re adding the preset manually instead of through init, install the plugins yourself:
npm install -D eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctorpnpm add -D eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctoryarn add -D eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctorbun add -D eslint-plugin-github eslint-plugin-sonarjs oxlint-plugin-react-doctorimport { defineConfig } from "oxlint";
import core from "ultracite/oxlint/core";
import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins";
export default defineConfig({
extends: [core, jsPlugins],
ignorePatterns: core.ignorePatterns,
settings: jsPluginSettings,
});
Note:
settings: jsPluginSettingsmust live on your root config — Oxlint does not mergesettingsfrom extended configs. It keeps React Doctor’s ported rules (such asonly-export-components) in their framework-aware “curated” mode, so Next.js route-segment exports likeexport const dynamic = "force-static"are not flagged as non-component exports.
In a Next.js or TanStack app, add the matching add-on preset as well:
import { defineConfig } from "oxlint";
import core from "ultracite/oxlint/core";
import next from "ultracite/oxlint/next";
import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins";
import nextJsPlugins from "ultracite/oxlint/next/js-plugins";
export default defineConfig({
extends: [core, next, jsPlugins, nextJsPlugins],
ignorePatterns: core.ignorePatterns,
settings: jsPluginSettings,
});
Anti-Slop Rules (Optional)
Ultracite also ships an opt-in anti-slop preset built on anti-slop, Dillon Mulroy’s set of opinionated Oxlint rules that reject low-evidence, low-signal TypeScript and JavaScript patterns — unjustified type assertions, unknown leaking through function signatures, Reflect-based property access, module mocking, and similar escape hatches.
Upstream is deliberately not published to npm (its distribution model is “copy the source into your repo”), so Ultracite vendors a self-contained bundled build of the plugin — there is nothing extra to install. Like js-plugins, this preset is off by default because it is strongly opinionated and runs through Oxlint’s slower JS-plugin pass.
You can enable it during setup: it appears as anti-slop in the same JS-plugins prompt as the packages above, and non-interactive setup accepts it via --js-plugins:
npx ultracite init --linter oxlint --js-plugins anti-sloppnpm dlx ultracite init --linter oxlint --js-plugins anti-slopyarn dlx ultracite init --linter oxlint --js-plugins anti-slopbunx ultracite init --linter oxlint --js-plugins anti-slopOr add it to your config manually:
import { defineConfig } from "oxlint";
import antiSlop from "ultracite/oxlint/anti-slop";
import core from "ultracite/oxlint/core";
export default defineConfig({
extends: [core, antiSlop],
ignorePatterns: core.ignorePatterns,
});
All fifteen rules are enabled at the error level, including require-safety-comment-for-type-assertion (every as assertion needs a SAFETY: comment stating the checked invariant), no-unknown-returns / no-unknown-parameters (parse values into named domain types at boundaries), and no-module-mocking (inject dependencies instead of mocking modules). If a rule doesn’t fit your codebase — no-module-mocking is a common example in test-heavy projects — turn it off in your own config’s rules block.
Configuration Approach
Ultracite’s Oxlint configuration uses an opt-out approach. This means we explicitly enable rules from every category at the error level, then selectively disable rules that are too strict or don’t fit our opinionated defaults. This ensures maximum bug-catching coverage while avoiding noise.
Rule Categories
Oxlint organizes rules into the following categories:
Correctness
Rules that catch definite bugs and errors. These are high-confidence rules that identify code that is almost certainly wrong.
Suspicious
Rules that catch code patterns that are likely bugs or mistakes. These have a slightly higher false-positive rate but catch important issues.
Pedantic
Rules that enforce stricter coding standards. These are more opinionated and may require more effort to satisfy.
Performance
Rules that identify performance issues and suggest optimizations for better runtime efficiency.
Restriction
Rules that restrict certain language features or patterns. These are typically project-specific preferences.
Style
Rules that enforce consistent code style across the codebase.
Included Plugins
Oxlint includes built-in support equivalent to these ESLint plugins:
- eslint — Core JavaScript rules
- typescript — TypeScript-specific rules
- unicorn — Opinionated code quality rules
- oxc — Oxc-specific optimizations
- import — Import/export validation
- jsdoc — JSDoc comment validation
- node — Node.js-specific rules
- promise — Promise and async/await best practices
- jest / vitest — Testing framework rules (enabled via the
jest/vitestframework presets)
For extra ESLint parity, the optional js-plugins preset adds github (eslint-plugin-github), sonarjs (eslint-plugin-sonarjs), and react-doctor (oxlint-plugin-react-doctor) via Oxlint’s JS plugin support. See ESLint Parity — it is not enabled by default.
Adding Third-Party Plugins
Oxlint supports community plugins for additional rules beyond the built-in set. For example, Ultracite’s Biome preset includes cognitive complexity checking via noExcessiveCognitiveComplexity, but Oxlint only has the standard cyclomatic complexity rule built in. You can close this gap with a third-party plugin like oxlint-plugin-complexity:
npm install -D oxlint-plugin-complexitypnpm add -D oxlint-plugin-complexityyarn add -D oxlint-plugin-complexitybun add -D oxlint-plugin-complexityimport { defineConfig } from "oxlint";
import core from "ultracite/oxlint/core";
export default defineConfig({
extends: [core],
ignorePatterns: core.ignorePatterns,
jsPlugins: ["oxlint-plugin-complexity"],
rules: {
"complexity/complexity": ["error", { cognitive: 15 }],
},
});
This approach lets you opt in to additional checks without Ultracite taking on third-party dependencies in its core preset.
Formatter Settings (Oxfmt)
Ultracite configures Oxfmt with these defaults:
- Indentation: 2 spaces
- Line Width: 80 characters
- Semicolons: Always required
- Double Quotes: Yes
- Trailing Commas: ES5 style
- Arrow Parentheses: Always include
- Tailwind Class Sorting: Enabled, including inside
clsx,cva,tw,twMerge,cn,twJoin, andtvcalls
Tailwind class sorting uses the same algorithm as prettier-plugin-tailwindcss. If you use Tailwind CSS v4 with a custom theme, point Oxfmt at your stylesheet so sorting respects your custom utilities:
import { defineConfig } from "oxfmt";
import ultracite from "ultracite/oxfmt";
export default defineConfig({
...ultracite,
sortTailwindcss: {
functions: ["clsx", "cva", "tw", "twMerge", "cn", "twJoin", "tv"],
stylesheet: "./app/globals.css",
},
});
Rule Reference
For the complete list of rules and their settings, see the Oxlint configuration on GitHub.
VS Code Extension
Install the Oxc extension for VS Code:
code --install-extension oxc.oxc-vscode