Config files
Configure React Doctor with a doctor.config.* file or the reactDoctor key in package.json. This page explains where React Doctor looks, which config wins, and how each common option changes a scan.
Where React Doctor looks
React Doctor starts in the scanned directory and walks up until it reaches .git or a monorepo root. Put doctor.config.ts or doctor.config.json next to the project you want to scan. You can also put the same object under reactDoctor in package.json.
Use one config per directory. If more than one exists, React Doctor uses the first valid config it finds and ignores lower-priority fallbacks. Local config wins over ancestor config.
JSON config files use JSON5, so comments and trailing commas are allowed. Add $schema: "https://react.doctor/schema/config.json" for editor autocomplete.
Command-line flags override config values.
Example config file
// doctor.config.ts
import { defineConfig } from "react-doctor/api";
export default defineConfig({
ignore: {
rules: ["react-doctor/no-danger"],
files: ["src/generated/**"],
overrides: [
{
files: ["components/search/HighlightedSnippet.tsx"],
rules: ["react-doctor/no-danger"],
},
],
},
rules: {
"react-doctor/no-array-index-as-key": "error",
},
categories: {
Maintainability: "warn",
},
});Use doctor.config.json for JSON config:
{
"$schema": "https://react.doctor/schema/config.json",
"ignore": {
"rules": ["react-doctor/no-danger"],
"files": ["src/generated/**"],
"overrides": [
{
"files": ["components/search/HighlightedSnippet.tsx"],
"rules": ["react-doctor/no-danger"]
}
]
},
"rules": {
"react-doctor/no-array-index-as-key": "error"
},
"categories": {
"Maintainability": "warn"
}
}Common keys
Use these keys to control scan scope, rule severity, output surfaces, and project-specific escape hatches.
| Key | Type | Default | Purpose |
|---|---|---|---|
ignore.rules | string[] | [] | Drop matching rule diagnostics after linting |
ignore.files | string[] | [] | Exclude matching files from scanning |
ignore.overrides | { files, rules? }[] | [] | Drop diagnostics for matching files or rules |
lint | boolean | true | Enable lint diagnostics |
deadCode | boolean | true | Run dead-code analysis (skipped in diff and staged modes) |
warnings | boolean | true | Surface warning-severity diagnostics |
verbose | boolean | false | Show more detail |
diff | boolean | string | Scan only changed files | |
blocking | "error" | "warning" | "none" | error | Severity that fails CI (exits non-zero) |
customRulesOnly | boolean | false | Run only configured custom rules |
share | boolean | true | Enable share URL behavior |
noScore | boolean | false | Skip the score API |
textComponents | string[] | [] | React Native text component aliases |
rawTextWrapperComponents | string[] | [] | React Native string wrapper components |
serverAuthFunctionNames | string[] | [] | Accepted server auth guard names |
respectInlineDisables | boolean | true | Respect inline lint disables |
adoptExistingLintConfig | boolean | true | Merge existing JSON lint config |
rootDir | string | Scan a different directory, resolved relative to the config file | |
ignore.tags | string[] | [] | Disable rule families by tag before linting |
rules | object | Set rule severity to | |
categories | object | Set category severity to | |
buckets | object | Set severity for curated buckets such as | |
surfaces | object | Control visibility on CLI, score, PR comments, and CI failure | |
plugins | string[] | [] | Load custom oxlint-shaped rule plugins |
Severity overrides use error, warn, or off. Per-rule rules entries win over categories; buckets currently supports compiler-cleanup for React Compiler cleanup rules.
Category overrides use the five buckets: Security, Bugs, Performance, Accessibility, and Maintainability.
Use rules or categories when you want to change severity or stop a rule from running. Use ignore.rules when you want the rule to run but drop its diagnostics from the final report. Use surfaces when you want a diagnostic to stay visible locally but disappear from PR comments, the score, or the CI failure gate.
React Native escape hatches
Use textComponents for components that behave like React Native's <Text>:
{
"textComponents": ["Typography", "NativeTabs.Trigger.Label"]
}Use rawTextWrapperComponents for components that route string children through an internal text component:
{
"rawTextWrapperComponents": ["Button"]
}Server auth guards
Use serverAuthFunctionNames when your server actions use custom auth helpers:
{
"serverAuthFunctionNames": ["requireWorkspaceMember", "ensureSignedIn"]
}Existing lint config
React Doctor can adopt JSON ESLint and oxlint config automatically. Set adoptExistingLintConfig: false if you want React Doctor to ignore existing lint config.
Narrow ignores and suppressions
Use the narrowest control that solves the problem. Ignore a rule everywhere only when it does not apply to your project:
{
"ignore": {
"rules": ["react-doctor/no-danger"]
}
}Ignore generated files when every diagnostic in those files is noise:
{
"ignore": {
"files": ["src/generated/**"]
}
}Ignore one rule in specific files when the exception is local:
{
"ignore": {
"overrides": [
{
"files": ["components/search/HighlightedSnippet.tsx"],
"rules": ["react-doctor/no-danger"]
}
]
}
}Use an inline suppression when the exception should live with the code:
// react-doctor-disable-next-line react-doctor/no-derived-state-effect
useEffect(() => {
setValue(initialValue);
}, []);Comma-separate rule names when one line needs more than one suppression. Use npx react-doctor@latest why src/App.tsx:42 when a suppression does not apply.
Custom rule plugins
React Doctor can run custom oxlint-shaped plugins from your config. Use this for team-specific conventions that do not belong in the core rule set:
{
"plugins": ["./lint/team-conventions.cjs"],
"rules": {
"team-conventions/no-bare-fetch": "error"
}
}Plugins export meta and rules:
module.exports = {
meta: {
name: "team-conventions",
},
rules: {
"no-bare-fetch": {
create(context) {
return {};
},
},
},
};Rule keys use <plugin-name>/<rule-name>. Plugin rules are opt-in and use the same CLI, score, PR comment, and CI surfaces as built-in rules.