Skip to content
Ultracite
Esc
↑↓navigate↵open⌘Jpreview

The strict Oxlint config, set up in one command

Oxlint ships 871 rules and turns on 111. Ultracite turns on 474 across eight plugins, sets up Oxfmt to match, and wires both into your editor and coding agents. Nothing to maintain but one line of extends.

Also onBiomeESLintChecked against Oxlint 1.87

import { defineConfig } from "oxlint";
import core from "ultracite/oxlint/core";474 rules
import react from "ultracite/oxlint/react";107 rules
import next from "ultracite/oxlint/next";21 rules

export default defineConfig({
  extends: [core, react, next],
  ignorePatterns: core.ignorePatterns,
});
602 rules, all errors
import { defineConfig } from "oxfmt";
import ultracite from "ultracite/oxfmt";

export default defineConfig({
  ...ultracite,
});
printWidth
80
singleQuote
false
semi
true
trailingComma
"es5"
sortImports
grouped, A–Z
sortTailwindcss
in cn(), cva()…

111 rules by default. 474 with Ultracite.

Out of the box, Oxlint only runs correctness rules: code that is definitely broken. Ultracite also turns on the suspicious, pedantic, style and restriction rules that catch what agents get wrong, like loose types, floating promises and nested ternaries.

Rules in Oxlint 1.87
871
On by default, all of them correctness rules
111
On in Ultracite’s core preset, before any framework rules
474
On by defaultTurned on by UltraciteLeft off
  • CorrectnessCode that’s outright wrong or useless

    125 / 125

  • SuspiciousCode that’s most likely wrong

    47 / 50

  • PedanticStricter checks that can flag code that works

    105 / 118

  • PerfCode that could run faster

    6 / 7

  • StyleCode with a more idiomatic form

    131 / 156

  • RestrictionBans on language and library features

    59 / 80

  • NurseryRules still in development

    1 / 10

eslint
166
unicorn
127
typescript
102
oxc
23
jsdoc
19
import
16
promise
13
node
8

Errors, never warnings

All 474 are set to error. An agent takes a zero exit code as done, and a warning doesn’t change it, so a warning is a problem nobody fixes.

56 rules that read your types

Rules like no-floating-promises and no-misused-promises need type information. They run once init --type-aware turns on Oxlint’s type-aware mode, on its typescript‑go backend.

Oxlint 1.87.0 and Ultracite 8.0.0. Categories count the 546 rules in the eight plugins the core preset enables, drawn to one scale; the React, Next.js, Vue, Jest and Vitest presets turn on rules from the other plugins.

Ten times the files, 4 more milliseconds

Oxlint and Oxfmt are native binaries that spread the work across every core, so a bigger project barely moves the clock. The ESLint toolchain runs in Node and slows down with every file you add.

42 files

Oxlint + Oxfmt

340 ms

ESLint + Prettier + Stylelint

3.91 s

420 files

Oxlint + Oxfmt

344 ms

ESLint + Prettier + Stylelint

15.5 s
Faster than the ESLint toolchain on 420 files
45×
Added on Oxlint going from 42 to 420 files
+4ms
Added on ESLint for the same growth
+11.6s
Medians of five runs of ultracite check on an Apple M1 Pro, through each toolchain’s core preset: Oxlint 1.87.0 and Oxfmt 0.71.0 against ESLint 10.12.0, Prettier 3.9.10 and Stylelint 17.16.0, on the repo’s benchmark fixture copied to 42 and 420 files. Times include starting Node and the CLI. How Biome compares.

Native rules by default, ESLint plugins when you ask

Every rule in the core and framework presets runs in Oxlint’s Rust engine. Plugins with no native port run through Oxlint’s ESLint-compatible JS plugin API, which adds a pass in Node, so they’re opt-in.

Native, in Rust

Core always, frameworks you pick
  • core · ESLint, TypeScript, Unicorn, imports, promises474

  • react · React, hooks and jsx-a11y107

  • vitest · Vitest test files63

  • jest · Jest test files56

  • vue · Vue script blocks45

  • next · Next.js21

JS plugins, through Node

Opt-in
  • js-plugins · eslint-plugin-sonarjs202

  • js-plugins · oxlint-plugin-react-doctor149

  • js-plugins · eslint-plugin-github21

  • anti-slop · Escape hatches agents reach for, vendored15

  • shadcn · @shadcn/lint, for Tailwind design systems6

$ npx ultracite init --linter oxlint --js-plugins eslint-plugin-sonarjs

Why they’re opt-in. Ultracite 7.9.1 folded the GitHub and SonarJS rules into core. On one user’s 22-file project, Oxlint went from 78 ms to 3.5 s (#741). Two releases later every JS plugin moved into its own preset, and every pull request now runs a benchmark that fails on a significant slowdown of 25% or more. How to set each one up is in Optional presets.

Oxfmt, set up like the Prettier config you’d write

Oxfmt is built to match Prettier’s output. Ultracite keeps Prettier’s 80-column width (Oxfmt defaults to 100), then turns on the sorting you’d otherwise install plugins for.

As written

import { cn } from '@/lib/utils'
import { Slot } from '@radix-ui/react-slot'
import type { ReactNode } from 'react'

export function Button({ asChild, children }: { asChild?: boolean, children: ReactNode }) {
  const Comp = asChild ? Slot : 'button'
  return <Comp className={cn('text-sm px-4 bg-primary hover:bg-primary/90 rounded-md h-10 font-medium')}>{children}</Comp>
}

After ultracite fix

import { Slot } from "@radix-ui/react-slot";
import type { ReactNode } from "react";

import { cn } from "@/lib/utils";

export function Button({
  asChild,
  children,
}: {
  asChild?: boolean;
  children: ReactNode;
}) {
  const Comp = asChild ? Slot : "button";
  return (
    <Comp
      className={cn(
        "bg-primary hover:bg-primary/90 h-10 rounded-md px-4 text-sm font-medium"
      )}
    >
      {children}
    </Comp>
  );
}
sortImports
Packages first, then your own aliases, with a blank line between the groups and A–Z order inside each.
sortTailwindcss
Tailwind classes in the order Tailwind’s Prettier plugin uses, in className and in cn, clsx, cva, tw, twMerge, twJoin and tv calls.
sortPackageJson
package.json keys in the conventional order, so a dependency an agent adds lands where a reviewer expects.

The same rules in your editor, your agent and CI

init points your editor at Oxlint and Oxfmt and tells your agents how to run them, so a file passes or fails the same way wherever it’s checked.

  1. {
      "[typescriptreact]": {
        "editor.defaultFormatter": "oxc.oxc-vscode"
      },
      "editor.codeActionsOnSave": {
        "source.fixAll.oxc": "explicit"
      },
      "editor.formatOnSave": true
    }

    VS Code, Cursor, Devin Desktop

    Fix and format on save

    The Oxc extension formats 16 languages, from TypeScript and CSS to YAML and Markdown, and applies Oxlint’s safe fixes when you save.

  2. "oxlint": {
      "initialization_options": {
        "settings": {
          "run": "onType",
          "typeAware": true,
          "unusedDisableDirectives": "deny"
        }
      }
    }

    Zed

    Lint as you type

    Oxlint’s language server checks each keystroke with the type-aware rules on, and a stale oxlint-disable comment is an error.

  3. Terminal

    $ npx ultracite check

    src/data.ts:20:14: error unicorn(no-array-sort): Use `Array#toSorted()` instead of `Array#sort()`.

    src/store.ts:1:22: error import(consistent-type-specifier-style): Prefer using a top-level type-only import instead of inline type specifiers.

    src/utils.ts:5:54: error eslint(sort-keys): Object keys should be sorted

    src/utils.ts:59:14: error eslint(no-await-in-loop): Unexpected `await` inside a loop.

    src/format.ts:42:6: error unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.

    Coding agents

    Output written for agents

    Oxlint notices when a coding agent runs it and prints one line per problem and no summary, to save tokens. init also writes the rules into AGENTS.md, which all 40 agents read.

Oxlint questions, answered

Is Oxlint a drop-in replacement for ESLint?
For most projects, yes. Oxlint implements 871 rules ported from ESLint, typescript-eslint, Unicorn, React, jsx-a11y, Next.js and other plugins under their original names, and loads ESLint v9-style plugins through its JS plugin API, which is still in alpha. It doesn’t support custom parsers, so in .vue, .svelte and .astro files only the script blocks are linted. If you need template linting, Ultracite’s ESLint provider has it.
What does Ultracite add on top of Oxlint’s defaults?
Oxlint enables 111 correctness rules by default. Ultracite’s core preset turns on 474 across eight plugins, every one set to error, and framework presets add more: 107 for React, 21 for Next.js, 45 for Vue, 56 for Jest and 63 for Vitest. init also writes a matching Oxfmt config, editor settings for VS Code and Zed, rules files for coding agents, and optional post-edit hooks.
How do I turn off a rule?
Set it in rules in your oxlint.config.ts. Oxlint applies the presets in extends first and your own rules after them, so rules: { "no-console": "off" } wins. For a single line, use // oxlint-disable-next-line no-console.
Do I still need Prettier?
No. Ultracite pairs Oxlint with Oxfmt, the Oxc formatter, set to Prettier’s defaults with import, Tailwind class and package.json sorting turned on. Oxfmt doesn’t run Prettier plugins, so if your project depends on one, pick Ultracite’s ESLint provider, which uses Prettier.
Should I use Oxlint or Biome?
Both are native and fast. In our benchmark, Biome checked 42 files in 257 ms to Oxlint’s 340 ms, and Oxlint was slightly ahead at 420 files, 344 ms to 379 ms. Pick Oxlint for the larger rule set (474 core rules to Biome’s 331), ESLint rule names and plugins, and type-aware rules built on typescript-go. Pick Biome if you’d rather have one tool and one config file.
How do I switch an existing project from ESLint?
Run npx ultracite init --linter oxlint. It removes the ESLint, Prettier and Stylelint packages it would have installed and their config files, moves an existing .oxlintrc.json into oxlint.config.ts, and merges into your .vscode/settings.json rather than replacing it. Copy any custom rules you want to keep into the new config.
Which frameworks does the Oxlint config cover?
Oxlint has native plugins for React, Next.js, Vue, Jest and Vitest, so those presets add rules. Svelte, Astro, Angular, Solid, Qwik, Remix, NestJS, TanStack, Cypress, Storybook, Playwright, React Native and Drizzle have no native plugin yet: their presets keep the config the same shape as on Biome and ESLint, and core’s rules still check their TypeScript and JavaScript.
Does it support type-aware rules?
Yes. Install with npx ultracite init --linter oxlint --type-aware, which adds oxlint-tsgolint and sets typeAware in oxlint.config.ts, so ultracite check, fix and the editor extension all run them. That turns on the 56 core rules that need type information, such as no-floating-promises and no-misused-promises, on Oxlint’s typescript-go backend.

Ship less slop

One command sets up your linter, formatter, editor and agents. Works with Oxlint, Biome and ESLint.