Presets
What each preset owns — one plugin or framework integration per preset, nothing implied by another.
Every preset owns a disjoint slice of rules and stands alone — none of them extends another. rules merge key-by-key and plugins/jsPlugins union when you list several in your own extends array, so pick every preset your project needs; nothing comes along for free.
The one exception is base.
base
Assumes no runtime, no framework, no UI library — JS/TS correctness and security rules any project wants, a Node CLI and a React app alike. The only bundled preset in the package, since there’s no meaningful way to want half of it.
| Preset | Adds |
|---|---|
@zap-studio/oxlint/base |
eslint, typescript, unicorn, oxc, import, promise, plus regexp, sonarjs, github, e18e, and the bundled anti-slop plugin |
React
Five independent presets. react alone gets hooks correctness only — accessibility, performance, and React-Doctor’s broader catalog are each their own opt-in.
| Preset | Owns |
|---|---|
@zap-studio/oxlint/react |
the react plugin — rules-of-hooks, exhaustive-deps |
@zap-studio/oxlint/react-a11y |
the jsx-a11y plugin, plus 4 accessibility checks from eslint-plugin-github with no jsx-a11y equivalent |
@zap-studio/oxlint/react-perf |
the react-perf plugin — the 4 jsx-no-new-*-as-prop rules |
@zap-studio/oxlint/react-doctor |
oxlint-plugin-react-doctor’s framework-agnostic rules — security, hydration, effect-timing, rendering correctness |
@zap-studio/oxlint/react-compiler |
the react/react-compiler rule, for projects on the React Compiler |
react-doctor’s rule catalog used to duplicate roughly 90 rules that react, react-perf, and jsx-a11y already cover under their own names — button-has-type, the entire jsx-a11y alt-text/aria/role catalog, all 4 react-perf prop-identity checks, and more. Those now live exclusively in the plugin they originate from; react-doctor only owns what’s genuinely original to it.
JSX runtime
react-in-jsx-scope depends on which JSX transform a project uses, so it’s a choice, not a default baked into react:
| Preset | Sets |
|---|---|
@zap-studio/oxlint/jsx-runtime-automatic |
react/react-in-jsx-scope: "off" — for jsx: "react-jsx" (the default in modern React/Next.js/Vite/Preact/React Native setups) |
@zap-studio/oxlint/jsx-runtime-classic |
react/react-in-jsx-scope: "warn" — for projects still on the classic transform |
Pick exactly one.
Framework & Library Leaves
Each of these owns only its own slice of oxlint-plugin-react-doctor’s framework-specific rules — no react, react-a11y, react-perf, or react-doctor bundled in. Add those separately (you almost always want them, for anything that renders JSX).
| Preset | Targets |
|---|---|
@zap-studio/oxlint/nextjs |
Next.js — App Router, metadata, route handlers, Image/Script/Head |
@zap-studio/oxlint/react-router |
React Router — loaders, actions, middleware, splat and nested routes |
@zap-studio/oxlint/react-native |
React Native/Expo — lists, Pressable, Reanimated, deprecated modules |
@zap-studio/oxlint/remotion |
Remotion — deterministic rendering, delayRender, CSS animation bans |
@zap-studio/oxlint/preact |
Preact — API differences from React (render args, hooks import, children) |
@zap-studio/oxlint/ink |
Ink — terminal rendering, raw mode, Static, focus handling |
@zap-studio/oxlint/r3f |
React Three Fiber |
@zap-studio/oxlint/three |
three.js |
@zap-studio/oxlint/motion |
Motion (Framer Motion) — AnimatePresence, imperative animation, layout ids |
@zap-studio/oxlint/redux |
Redux — useSelector derivation and return-value pitfalls |
@zap-studio/oxlint/zustand |
Zustand — selector freshness, store mutation, whole-store destructuring |
@zap-studio/oxlint/valtio |
Valtio — proxy reads and snapshots |
@zap-studio/oxlint/mobx |
MobX — observer/memo interaction, makeAutoObservable, reaction disposal |
@zap-studio/oxlint/jotai |
Jotai — derived atoms, selectAtom placement |
@zap-studio/oxlint/styled-components |
styled-components — duplicate CSS properties, transient props |
@zap-studio/oxlint/tanstack-query |
TanStack Query — @tanstack/eslint-plugin-query plus react-doctor’s 9 query-pattern rules (floating mutations, missing invalidation, unstable query clients) |
@zap-studio/oxlint/tanstack-start |
TanStack Start — react-doctor’s 15 meta-framework rules (loaders, route property order, server functions, secrets in loaders) |
@zap-studio/oxlint/tanstack-router |
TanStack Router — @tanstack/eslint-plugin-router |
@zap-studio/oxlint/solid |
Solid — eslint-plugin-solid’s reactivity/JSX rules (props destructuring, no-innerhtml, prefer-for); not a react-doctor slice, Solid’s reactivity model is its own |
@zap-studio/oxlint/stylex |
StyleX — @stylexjs/eslint-plugin’s full rule set: valid/standard styles, unsafe shorthands, unused styles, conflicting props |
@zap-studio/oxlint/tailwindcss |
Tailwind CSS v4 — eslint-plugin-tailwindcss’s contradicting/unnecessary-arbitrary-value and class-order rules |
Preact and React Native are runtime-ambiguous — pair either with jsx-runtime-automatic or jsx-runtime-classic depending on the project’s transform. Solid uses its own JSX transform (babel-preset-solid), not React’s, so neither jsx-runtime preset applies to it.
Opt-in Environment Presets
Not every project runs in Node or wants JSDoc type-annotation rules enforced (redundant once a project is on TypeScript, which base already assumes) — kept separate from base for that reason:
| Preset | Adds |
|---|---|
@zap-studio/oxlint/jsdoc |
the jsdoc plugin — for JS (or intentionally-untyped) code |
@zap-studio/oxlint/node |
the node plugin — for code that actually runs under Node |
Testing
Split by test runner:
| Preset | Adds |
|---|---|
@zap-studio/oxlint/vitest |
the vitest plugin |
@zap-studio/oxlint/playwright |
eslint-plugin-playwright |
@zap-studio/oxlint/cypress |
eslint-plugin-cypress |
@zap-studio/oxlint/testing-library |
eslint-plugin-testing-library’s framework-agnostic DOM query/async rules |
@zap-studio/oxlint/jest-dom |
eslint-plugin-jest-dom — its matcher rules work under both Jest and Vitest’s jest-dom-compatible expect |
Storybook
| Preset | Adds |
|---|---|
@zap-studio/oxlint/storybook |
eslint-plugin-storybook’s story-file correctness and CSF-format rules |
Example: Next.js + TanStack, React Compiler on
import { defineConfig } from "oxlint";
import {
base,
react,
reactA11y,
reactDoctor,
reactCompiler,
jsxRuntimeAutomatic,
nextjs,
tanstackQuery,
vitest,
} from "@zap-studio/oxlint";
export default defineConfig({
extends: [
base,
react,
reactA11y,
reactDoctor,
reactCompiler,
jsxRuntimeAutomatic,
nextjs,
tanstackQuery,
vitest,
],
});
Nine imports instead of one — the tradeoff for a preset stack that’s exactly what the project uses, nothing implied.
Where the Rules Come From
Every plugin named in the tables above — built-in or external — traces back to an upstream project or, for anti-slop, this repo directly. See Plugins for the source of each one and a link to the file where its rules are decided on or off.