Skip to content

Configuration

Select one nested policy level, optional project contexts, and the independent AI overlay.

getOxlintConfig() accepts one policy level and three independent selectors:

type ConfigOptions = {
  level?: "essential" | "recommended" | "strict";
  react?: boolean;
  node?: boolean;
  ai?: boolean;
};

All options are fixed selectors for prebuilt artifacts. They do not dynamically assemble a configuration at consumer runtime.

Policy levels

Essential

Use essential as the lowest-noise adoption baseline. It materializes Oxlint's stable correctness category and applies the repository's curated overrides.

Recommended adds the stable suspicious and perf categories and is the default. Start here for a new TypeScript project unless migration cost requires a smaller first step.

Strict

Strict adds pedantic, style, and restriction. It therefore contains every stable Oxlint category except nursery. Selecting Strict is an explicit team decision, not a side effect of enabling another feature.

The levels are nested:

essential < recommended < strict

Levels control rule membership only. When a curated rule exists in several levels, its base severity and options stay identical. Moving up only adds policy. nursery remains disabled at every level.

During the build, the pinned Oxlint binary expands each category draft into explicit rules. Published JSON contains categories turned off and the complete materialized rule map. This makes dependency changes reviewable and lets the customization helpers target every active rule.

Project context

react: true adds native React and JSX accessibility categories. node: true adds native server-runtime and module-system rules. Both combine with every policy level.

export default getOxlintConfig({
  level: "recommended",
  react: true,
  node: true,
});

React coverage and boundaries

The stable React selector is native Oxlint only. Its repository-owned behavior suite covers Rules of Hooks, effect dependencies, list keys, duplicate JSX properties, invalid DOM properties, unsafe links, high-signal accessibility, React Refresh export boundaries, and representative allocation checks. The native React rules own those defect classes; a JavaScript React or react-hooks plugin cannot enter a stable configuration, and the ledger rejects an overlapping native and JavaScript owner.

Defect classProduct decision
Hook order and effect dependenciesStable native React diagnostics
Missing or index list keys; duplicate JSX and invalid DOM propertiesStable native React diagnostics
Unsafe links; missing text alternatives; pointer-only actionsStable native React and JSX accessibility diagnostics
React Refresh export boundariesStable native diagnostic at the strict level
Constructed context values and unstable nested componentsStable native performance diagnostics; AI mode inherits them without adding React rules
State updates during render or effects; unnecessary effectsDocumented non-goal pending adequate native evidence
Leaked listeners, timers, intervals, and observersDocumented non-goal pending adequate native evidence
React Compiler diagnosticsWarning-only named experimental configuration

The suite deliberately does not claim diagnostics for state updates during render or effects, unnecessary effects, or leaked event listeners, timers, and observers. The pinned native surface does not provide adequate evidence for those behaviors. Keep their lifecycle ownership in review or adopt a separate tool; they are not silently covered by the React selector.

AI mode does not add a JavaScript React plugin or change the React ownership model. It executes the same native allocation and performance diagnostics as the selected React policy level. react/react-compiler remains a separate, warning-only experimental configuration and is never selected by react: true.

AI is independent

ai: true does not select a stricter level or enable another category. It tightens already-active rules and adds rules explicitly classified as AI-only. See AI mode for the guardrails.

Mixed repositories

Use getComposedOxlintConfig() when contexts apply to file groups rather than the whole repository. It uses the same prebuilt type-aware root artifacts and adds stable native overrides:

import { getComposedOxlintConfig } from "oxlint-config-setup";

export default getComposedOxlintConfig({
  scopes: [
    "react",
    { scope: "node", files: ["packages/api/**/*.{ts,mts}"] },
    "vitest",
    "scripts",
  ],
});

react, node, vitest, jest, scripts, config, and declarations are available scopes. Test scopes only match canonical *.test.{ts,tsx} and __tests__/**/*.{ts,tsx} patterns. Consumer overrides append after package fragments; their plugin arrays are unioned with required plugins so an override cannot accidentally replace them. Rules, environments, and globals then follow Oxlint's normal later-override behavior.

Select either the Vitest or Jest scope for one configuration. The loader rejects both together because their runner rules overlap.

Testing Library rules apply automatically to canonical *.test.{ts,tsx} and __tests__/**/*.{ts,tsx} files in the type-aware TypeScript loaders. The plugin's flat/dom preset is the default; selecting React switches the test-file override to flat/react. This does not depend on a selected test runner, and the package supplies the required runtime.

The composition API is TypeScript-only because it constructs file overrides at runtime. The same loaders automatically apply Playwright's flat/recommended preset to *.spec.ts files and Storybook's flat/recommended story rules to *.stories.{ts,tsx} files. Neither has a runner dependency. Public JSON exports remain core-only configurations because copied JSON cannot retain package-relative plugin paths.

Defaults

OptionDefault
level"recommended"
reactfalse
nodefalse
aifalse

Unknown keys and invalid values throw before an artifact is loaded.