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
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 < strictLevels 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 class | Product decision |
|---|---|
| Hook order and effect dependencies | Stable native React diagnostics |
| Missing or index list keys; duplicate JSX and invalid DOM properties | Stable native React diagnostics |
| Unsafe links; missing text alternatives; pointer-only actions | Stable native React and JSX accessibility diagnostics |
| React Refresh export boundaries | Stable native diagnostic at the strict level |
| Constructed context values and unstable nested components | Stable native performance diagnostics; AI mode inherits them without adding React rules |
| State updates during render or effects; unnecessary effects | Documented non-goal pending adequate native evidence |
| Leaked listeners, timers, intervals, and observers | Documented non-goal pending adequate native evidence |
| React Compiler diagnostics | Warning-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
| Option | Default |
|---|---|
level | "recommended" |
react | false |
node | false |
ai | false |
Unknown keys and invalid values throw before an artifact is loaded.