react-doctor 0.0.46 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -238
- package/dist/cli.js +824 -114
- package/dist/eslint-plugin.d.ts +57 -0
- package/dist/eslint-plugin.js +6965 -0
- package/dist/index.d.ts +33 -2
- package/dist/index.js +940 -400
- package/dist/react-doctor-plugin.js +2010 -320
- package/package.json +9 -13
- package/dist/browser-BOxs7MrK.js +0 -359
- package/dist/browser-Dcq3yn-p.d.ts +0 -146
- package/dist/browser.d.ts +0 -2
- package/dist/browser.js +0 -2
- package/dist/worker.d.ts +0 -2
- package/dist/worker.js +0 -2
package/README.md
CHANGED
|
@@ -7,22 +7,13 @@
|
|
|
7
7
|
[](https://npmjs.com/package/react-doctor)
|
|
8
8
|
[](https://npmjs.com/package/react-doctor)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Your agent writes bad React, this catches it.
|
|
11
11
|
|
|
12
|
-
One command scans your codebase
|
|
12
|
+
One command scans your codebase and outputs a **0 to 100 health score** with actionable diagnostics.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
https://github.com/user-attachments/assets/07cc88d9-9589-44c3-aa73-5d603cb1c570
|
|
17
|
-
|
|
18
|
-
## How it works
|
|
19
|
-
|
|
20
|
-
React Doctor detects your framework (Next.js, Vite, Remix, etc.), React version, and compiler setup, then runs two analysis passes **in parallel**:
|
|
21
|
-
|
|
22
|
-
1. **Lint**: Checks 60+ rules across state & effects, performance, architecture, bundle size, security, correctness, accessibility, and framework-specific categories (Next.js, React Native). Rules are toggled automatically based on your project setup.
|
|
23
|
-
2. **Dead code**: Detects unused files, exports, types, and duplicates.
|
|
14
|
+
Works with Next.js, Vite, and React Native.
|
|
24
15
|
|
|
25
|
-
|
|
16
|
+
### [See it in action →](https://react.doctor)
|
|
26
17
|
|
|
27
18
|
## Install
|
|
28
19
|
|
|
@@ -32,23 +23,21 @@ Run this at your project root:
|
|
|
32
23
|
npx -y react-doctor@latest .
|
|
33
24
|
```
|
|
34
25
|
|
|
35
|
-
|
|
26
|
+
You'll get a score (75+ Great, 50 to 74 Needs work, under 50 Critical) and a list of issues across state & effects, performance, architecture, security, accessibility, and dead code. Rules toggle automatically based on your framework and React version.
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
npx -y react-doctor@latest . --verbose
|
|
39
|
-
```
|
|
28
|
+
https://github.com/user-attachments/assets/07cc88d9-9589-44c3-aa73-5d603cb1c570
|
|
40
29
|
|
|
41
30
|
## Install for your coding agent
|
|
42
31
|
|
|
43
|
-
Teach your coding agent React best practices
|
|
32
|
+
Teach your coding agent React best practices so it stops writing the bad code in the first place.
|
|
44
33
|
|
|
45
34
|
```bash
|
|
46
35
|
npx -y react-doctor@latest install
|
|
47
36
|
```
|
|
48
37
|
|
|
49
|
-
You'll be prompted to pick which detected agents to install for. Pass `--yes` to skip prompts
|
|
38
|
+
You'll be prompted to pick which detected agents to install for. Pass `--yes` to skip prompts.
|
|
50
39
|
|
|
51
|
-
|
|
40
|
+
Works with Claude Code, Cursor, Codex, OpenCode, and 50+ other agents.
|
|
52
41
|
|
|
53
42
|
## GitHub Actions
|
|
54
43
|
|
|
@@ -62,289 +51,168 @@ Supports 50+ coding agents via [`agent-install`](https://www.npmjs.com/package/a
|
|
|
62
51
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
63
52
|
```
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
| -------------- | ------- | ----------------------------------------------------------------- |
|
|
67
|
-
| `directory` | `.` | Project directory to scan |
|
|
68
|
-
| `verbose` | `true` | Show file details per rule |
|
|
69
|
-
| `project` | | Workspace project(s) to scan (comma-separated) |
|
|
70
|
-
| `diff` | | Base branch for diff mode. Only changed files are scanned |
|
|
71
|
-
| `github-token` | | When set on `pull_request` events, posts findings as a PR comment |
|
|
72
|
-
| `fail-on` | `error` | Exit with error code on diagnostics: `error`, `warning`, `none` |
|
|
73
|
-
| `offline` | `false` | Skip sending diagnostics to the react.doctor API |
|
|
74
|
-
| `node-version` | `22` | Node.js version to use |
|
|
75
|
-
|
|
76
|
-
The action outputs a `score` (0–100) you can use in subsequent steps.
|
|
77
|
-
|
|
78
|
-
## Options
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
Usage: react-doctor [directory] [options]
|
|
82
|
-
|
|
83
|
-
Options:
|
|
84
|
-
-v, --version display the version number
|
|
85
|
-
--no-lint skip linting
|
|
86
|
-
--no-dead-code skip dead code detection
|
|
87
|
-
--verbose show file details per rule
|
|
88
|
-
--score output only the score
|
|
89
|
-
--json output a single structured JSON report (suppresses other output)
|
|
90
|
-
-y, --yes skip prompts, scan all workspace projects
|
|
91
|
-
--full skip prompts, always run a full scan (decline diff-only)
|
|
92
|
-
--project <name> select workspace project (comma-separated for multiple)
|
|
93
|
-
--diff [base] scan only files changed vs base branch
|
|
94
|
-
--offline skip telemetry (anonymous, not stored, only used to calculate score)
|
|
95
|
-
--staged scan only staged (git index) files for pre-commit hooks
|
|
96
|
-
--fail-on <level> exit with error code on diagnostics: error, warning, none
|
|
97
|
-
--annotations output diagnostics as GitHub Actions annotations
|
|
98
|
-
-h, --help display help for command
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## JSON output
|
|
102
|
-
|
|
103
|
-
Pass `--json` to get a single, parsable JSON object on stdout. All human-readable output, prompts, and the share link are suppressed; pipe straight into `jq`, `node`, or any other tool:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
npx -y react-doctor@latest . --json | jq '.summary'
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Exit code is `0` on success and `1` if the scan throws or `--fail-on` is triggered. Errors still produce a JSON object with `ok: false`, so the stdout is always a valid document.
|
|
110
|
-
|
|
111
|
-
### Schema
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
interface JsonReport {
|
|
115
|
-
schemaVersion: 1;
|
|
116
|
-
version: string; // react-doctor version
|
|
117
|
-
ok: boolean; // false when an error was thrown
|
|
118
|
-
directory: string; // resolved root passed to the CLI
|
|
119
|
-
mode: "full" | "diff" | "staged";
|
|
120
|
-
diff: {
|
|
121
|
-
baseBranch: string;
|
|
122
|
-
currentBranch: string;
|
|
123
|
-
changedFileCount: number;
|
|
124
|
-
isCurrentChanges: boolean;
|
|
125
|
-
} | null;
|
|
126
|
-
projects: Array<{
|
|
127
|
-
directory: string;
|
|
128
|
-
project: ProjectInfo;
|
|
129
|
-
diagnostics: Diagnostic[];
|
|
130
|
-
score: { score: number; label: string } | null;
|
|
131
|
-
skippedChecks: string[];
|
|
132
|
-
elapsedMilliseconds: number;
|
|
133
|
-
}>;
|
|
134
|
-
diagnostics: Diagnostic[]; // flattened across all scanned projects
|
|
135
|
-
summary: {
|
|
136
|
-
errorCount: number;
|
|
137
|
-
warningCount: number;
|
|
138
|
-
affectedFileCount: number;
|
|
139
|
-
totalDiagnosticCount: number;
|
|
140
|
-
score: number | null; // worst project score, when available
|
|
141
|
-
scoreLabel: string | null;
|
|
142
|
-
};
|
|
143
|
-
elapsedMilliseconds: number; // total wall time across all projects
|
|
144
|
-
error: {
|
|
145
|
-
message: string;
|
|
146
|
-
name: string;
|
|
147
|
-
chain: string[]; // outer error message first, every `error.cause`
|
|
148
|
-
// unwrapped after; chain[0] always equals `message`
|
|
149
|
-
} | null; // null on success, populated when ok=false
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## Browser API
|
|
154
|
-
|
|
155
|
-
Import `react-doctor/browser` to run the same **diagnostics merge, config-based filtering, timing, and scoring pipeline** as `react-doctor/api`’s `diagnose`, but with **caller-supplied** inputs: `project` metadata, a virtual `projectFiles` map (contents keyed by paths relative to `rootDirectory`) for ignore/suppression resolution, and a `runOxlint` callback that performs linting in your environment (for example a Web Worker with oxlint).
|
|
156
|
-
|
|
157
|
-
Git history, real filesystem discovery, knip, the CLI, staged-file detection, and interactive prompts are **not** available in the browser bundle; treat those as Node-only or supply equivalents yourself. `react-doctor/worker` re-exports the same browser-facing modules for worker targets.
|
|
158
|
-
|
|
159
|
-
If you call **`diagnoseCore`** yourself in the browser, pass **`calculateDiagnosticsScore`** from this package (re-exported as **`calculateScore`** on `react-doctor/browser`) so the bundle never pulls in Node-only proxy code.
|
|
54
|
+
When `github-token` is set on `pull_request` events, findings are posted as a PR comment. The action also outputs a `score` (0 to 100) you can use in subsequent steps.
|
|
160
55
|
|
|
161
56
|
## Configuration
|
|
162
57
|
|
|
163
|
-
Create a `react-doctor.config.json` in your project root
|
|
58
|
+
Create a `react-doctor.config.json` in your project root:
|
|
164
59
|
|
|
165
60
|
```json
|
|
166
61
|
{
|
|
167
62
|
"ignore": {
|
|
168
|
-
"rules": ["react/no-danger", "jsx-a11y/no-autofocus"
|
|
169
|
-
"files": ["src/generated/**"]
|
|
63
|
+
"rules": ["react/no-danger", "jsx-a11y/no-autofocus"],
|
|
64
|
+
"files": ["src/generated/**"],
|
|
65
|
+
"overrides": [
|
|
66
|
+
{
|
|
67
|
+
"files": ["components/diff/**"],
|
|
68
|
+
"rules": ["react-doctor/no-array-index-as-key"]
|
|
69
|
+
}
|
|
70
|
+
]
|
|
170
71
|
}
|
|
171
72
|
}
|
|
172
73
|
```
|
|
173
74
|
|
|
174
|
-
You can also use the `"reactDoctor"` key in
|
|
75
|
+
`ignore.rules` silences a rule everywhere. `ignore.files` silences every rule on matched files. `ignore.overrides` silences specific rules in specific directories. You can also use the `"reactDoctor"` key in `package.json`. CLI flags always override config values.
|
|
175
76
|
|
|
176
|
-
|
|
177
|
-
{
|
|
178
|
-
"reactDoctor": {
|
|
179
|
-
"ignore": {
|
|
180
|
-
"rules": ["react/no-danger"]
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
```
|
|
77
|
+
React Doctor respects `.gitignore`, `.eslintignore`, `.oxlintignore`, `.prettierignore`, and `linguist-vendored` / `linguist-generated` annotations in `.gitattributes`. Inline `// eslint-disable*` and `// oxlint-disable*` comments are honored too.
|
|
185
78
|
|
|
186
|
-
If
|
|
79
|
+
If you have a JSON oxlint or eslint config (`.oxlintrc.json` or `.eslintrc.json`), its rules get merged into the scan automatically and count toward the score. Set `adoptExistingLintConfig: false` to opt out.
|
|
187
80
|
|
|
188
81
|
### Inline suppressions
|
|
189
82
|
|
|
190
|
-
Suppress a rule on a specific line with `// react-doctor-disable-line` or the next line with `// react-doctor-disable-next-line`:
|
|
191
|
-
|
|
192
83
|
```tsx
|
|
193
84
|
// react-doctor-disable-next-line react-doctor/no-cascading-set-state
|
|
194
85
|
useEffect(() => {
|
|
195
86
|
setA(value);
|
|
196
87
|
setB(value);
|
|
197
|
-
setC(value);
|
|
198
88
|
}, [value]);
|
|
199
|
-
|
|
200
|
-
const value = expensiveComputation(); // react-doctor-disable-line react-doctor/no-usememo-simple-expression
|
|
201
89
|
```
|
|
202
90
|
|
|
203
|
-
|
|
91
|
+
When two rules fire on the same line, comma-separate the rule ids on a single comment. Block comments work inside JSX:
|
|
204
92
|
|
|
205
|
-
|
|
93
|
+
<!-- prettier-ignore -->
|
|
94
|
+
```tsx
|
|
95
|
+
{/* react-doctor-disable-next-line react/no-danger */}
|
|
96
|
+
<div dangerouslySetInnerHTML={{ __html }} />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For multi-line JSX, putting the comment immediately above the opening tag covers the entire attribute list (matching ESLint convention).
|
|
206
100
|
|
|
207
|
-
|
|
101
|
+
## Lint plugin (standalone)
|
|
208
102
|
|
|
209
|
-
|
|
210
|
-
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
211
|
-
| `.gitignore` | files git ignores (oxlint default) |
|
|
212
|
-
| `.eslintignore` | files eslint skips (oxlint default) |
|
|
213
|
-
| `.oxlintignore` | files oxlint skips (added via `--ignore-pattern` so `.eslintignore` still applies) |
|
|
214
|
-
| `.prettierignore` | files prettier skips — typically vendored code, generated builds, and lockfiles |
|
|
215
|
-
| `.gitattributes` (`linguist-vendored`, `linguist-generated`) | paths GitHub's linguist library hides from language stats; if it's not "your" code by GitHub's reckoning, it shouldn't be audited as your code by react-doctor either |
|
|
103
|
+
The same rule set ships as both an oxlint plugin and an ESLint plugin, so you can wire it into whichever lint engine your project already runs.
|
|
216
104
|
|
|
217
|
-
|
|
105
|
+
**oxlint** in `.oxlintrc.json`:
|
|
218
106
|
|
|
219
|
-
|
|
220
|
-
|
|
107
|
+
```jsonc
|
|
108
|
+
{
|
|
109
|
+
"jsPlugins": [{ "name": "react-doctor", "specifier": "react-doctor/oxlint-plugin" }],
|
|
110
|
+
"rules": {
|
|
111
|
+
"react-doctor/no-fetch-in-effect": "warn",
|
|
112
|
+
"react-doctor/no-derived-state-effect": "warn",
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
```
|
|
221
116
|
|
|
222
|
-
|
|
117
|
+
**ESLint** flat config:
|
|
223
118
|
|
|
224
|
-
|
|
119
|
+
```js
|
|
120
|
+
import reactDoctor from "react-doctor/eslint-plugin";
|
|
225
121
|
|
|
226
|
-
|
|
227
|
-
|
|
122
|
+
export default [
|
|
123
|
+
reactDoctor.configs.recommended,
|
|
124
|
+
reactDoctor.configs.next,
|
|
125
|
+
reactDoctor.configs["react-native"],
|
|
126
|
+
reactDoctor.configs["tanstack-start"],
|
|
127
|
+
reactDoctor.configs["tanstack-query"],
|
|
128
|
+
];
|
|
228
129
|
```
|
|
229
130
|
|
|
230
|
-
|
|
131
|
+
The full rule list lives in [`oxlint-config.ts`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/oxlint-config.ts).
|
|
231
132
|
|
|
232
|
-
|
|
133
|
+
## CLI reference
|
|
233
134
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
| `ignore.rules` | `string[]` | `[]` | Rules to suppress, using the `plugin/rule` format shown in diagnostic output (e.g. `react/no-danger`, `knip/exports`, `knip/types`) |
|
|
237
|
-
| `ignore.files` | `string[]` | `[]` | File paths to exclude, supports glob patterns (`src/generated/**`, `**/*.test.tsx`) |
|
|
238
|
-
| `lint` | `boolean` | `true` | Enable/disable lint checks (same as `--no-lint`) |
|
|
239
|
-
| `deadCode` | `boolean` | `true` | Enable/disable dead code detection (same as `--no-dead-code`) |
|
|
240
|
-
| `verbose` | `boolean` | `false` | Show file details per rule (same as `--verbose`) |
|
|
241
|
-
| `diff` | `boolean \| string` | — | Force diff mode (`true`) or pin a base branch (`"main"`). Set to `false` to disable auto-detection. |
|
|
242
|
-
| `failOn` | `"error" \| "warning" \| "none"` | `"none"` | Exit with error code on diagnostics of the given severity or above |
|
|
243
|
-
| `customRulesOnly` | `boolean` | `false` | Disable built-in react/jsx-a11y/compiler rules, keeping only `react-doctor/*` plugin rules |
|
|
244
|
-
| `share` | `boolean` | `true` | Show the share-your-results URL after scanning |
|
|
245
|
-
| `textComponents` | `string[]` | `[]` | React Native only. Component names whose children should not trigger `rn-no-raw-text` (e.g. `["MyText", "Label.Bold"]`) |
|
|
246
|
-
| `respectInlineDisables` | `boolean` | `true` | Respect inline `// eslint-disable*` / `// oxlint-disable*` comments. Set `false` for audit mode. File-level ignores (`.gitignore`, `.eslintignore`, `.oxlintignore`, `.prettierignore`, `.gitattributes` linguist annotations) are always respected. |
|
|
135
|
+
```
|
|
136
|
+
Usage: react-doctor [directory] [options]
|
|
247
137
|
|
|
248
|
-
|
|
138
|
+
Options:
|
|
139
|
+
-v, --version display the version number
|
|
140
|
+
--no-lint skip linting
|
|
141
|
+
--no-dead-code skip dead code detection
|
|
142
|
+
--verbose show every rule and per-file details (default shows top 3 rules)
|
|
143
|
+
--score output only the score
|
|
144
|
+
--json output a single structured JSON report
|
|
145
|
+
-y, --yes skip prompts, scan all workspace projects
|
|
146
|
+
--full skip prompts, always run a full scan
|
|
147
|
+
--project <name> select workspace project (comma-separated for multiple)
|
|
148
|
+
--diff [base] scan only files changed vs base branch
|
|
149
|
+
--staged scan only staged files (for pre-commit hooks)
|
|
150
|
+
--offline skip telemetry
|
|
151
|
+
--fail-on <level> exit with error on diagnostics: error, warning, none
|
|
152
|
+
--annotations output diagnostics as GitHub Actions annotations
|
|
153
|
+
--explain <file:line> diagnose why a rule fired or why a suppression didn't apply
|
|
154
|
+
-h, --help display help
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
When a suppression isn't working, `--explain <file:line>` reports what the scanner sees at that location, including why a nearby `react-doctor-disable-next-line` didn't apply. The same hint surfaces inline with `--verbose` and in `--json` output as `diagnostic.suppressionHint`.
|
|
158
|
+
|
|
159
|
+
`--json` produces a parsable object on stdout with all human-readable output suppressed. Errors still produce a JSON object with `ok: false`, so stdout is always a valid document.
|
|
160
|
+
|
|
161
|
+
### Config keys
|
|
162
|
+
|
|
163
|
+
| Key | Type | Default |
|
|
164
|
+
| ------------------------- | -------------------------------- | -------- |
|
|
165
|
+
| `ignore.rules` | `string[]` | `[]` |
|
|
166
|
+
| `ignore.files` | `string[]` | `[]` |
|
|
167
|
+
| `ignore.overrides` | `{ files, rules? }[]` | `[]` |
|
|
168
|
+
| `lint` | `boolean` | `true` |
|
|
169
|
+
| `deadCode` | `boolean` | `true` |
|
|
170
|
+
| `verbose` | `boolean` | `false` |
|
|
171
|
+
| `diff` | `boolean \| string` | |
|
|
172
|
+
| `failOn` | `"error" \| "warning" \| "none"` | `"none"` |
|
|
173
|
+
| `customRulesOnly` | `boolean` | `false` |
|
|
174
|
+
| `share` | `boolean` | `true` |
|
|
175
|
+
| `textComponents` | `string[]` | `[]` |
|
|
176
|
+
| `respectInlineDisables` | `boolean` | `true` |
|
|
177
|
+
| `adoptExistingLintConfig` | `boolean` | `true` |
|
|
249
178
|
|
|
250
179
|
## Node.js API
|
|
251
180
|
|
|
252
|
-
You can also use React Doctor programmatically:
|
|
253
|
-
|
|
254
181
|
```js
|
|
255
|
-
import { diagnose } from "react-doctor/api";
|
|
182
|
+
import { diagnose, toJsonReport, summarizeDiagnostics } from "react-doctor/api";
|
|
256
183
|
|
|
257
184
|
const result = await diagnose("./path/to/your/react-project");
|
|
258
185
|
|
|
259
186
|
console.log(result.score); // { score: 82, label: "Great" } or null
|
|
260
|
-
console.log(result.diagnostics); //
|
|
261
|
-
console.log(result.project); //
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
The `diagnose` function accepts an optional second argument:
|
|
265
|
-
|
|
266
|
-
```js
|
|
267
|
-
const result = await diagnose(".", {
|
|
268
|
-
lint: true, // run lint checks (default: true)
|
|
269
|
-
deadCode: true, // run dead code detection (default: true)
|
|
270
|
-
});
|
|
187
|
+
console.log(result.diagnostics); // Diagnostic[]
|
|
188
|
+
console.log(result.project); // detected framework, React version, etc.
|
|
271
189
|
```
|
|
272
190
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
```ts
|
|
276
|
-
interface Diagnostic {
|
|
277
|
-
filePath: string;
|
|
278
|
-
plugin: string;
|
|
279
|
-
rule: string;
|
|
280
|
-
severity: "error" | "warning";
|
|
281
|
-
message: string;
|
|
282
|
-
help: string;
|
|
283
|
-
line: number;
|
|
284
|
-
column: number;
|
|
285
|
-
category: string;
|
|
286
|
-
}
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
To produce the same structured output the `--json` CLI flag emits, use `toJsonReport`:
|
|
191
|
+
`diagnose` accepts a second argument: `{ lint?: boolean, deadCode?: boolean }`.
|
|
290
192
|
|
|
291
193
|
```js
|
|
292
|
-
import { diagnose, toJsonReport, summarizeDiagnostics } from "react-doctor/api";
|
|
293
|
-
|
|
294
|
-
const result = await diagnose(".");
|
|
295
|
-
|
|
296
194
|
const report = toJsonReport(result, { version: "1.0.0" });
|
|
297
|
-
console.log(JSON.stringify(report, null, 2));
|
|
298
|
-
|
|
299
195
|
const counts = summarizeDiagnostics(result.diagnostics);
|
|
300
|
-
console.log(`${counts.errorCount} errors, ${counts.warningCount} warnings`);
|
|
301
196
|
```
|
|
302
197
|
|
|
303
|
-
`react-doctor/api`
|
|
198
|
+
`react-doctor/api` re-exports `JsonReport`, `JsonReportSummary`, `JsonReportProjectEntry`, `JsonReportMode`, plus the lower-level `buildJsonReport` and `buildJsonReportError` builders. See [`packages/react-doctor/src/api.ts`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/api.ts) for the full types.
|
|
304
199
|
|
|
305
|
-
##
|
|
200
|
+
## Resources & Contributing Back
|
|
306
201
|
|
|
307
|
-
|
|
202
|
+
Want to try it out? Check out [the demo](https://react.doctor).
|
|
308
203
|
|
|
309
|
-
|
|
310
|
-
{
|
|
311
|
-
"jsPlugins": [
|
|
312
|
-
{
|
|
313
|
-
"name": "react-doctor",
|
|
314
|
-
"specifier": "react-doctor/oxlint-plugin",
|
|
315
|
-
},
|
|
316
|
-
],
|
|
317
|
-
"rules": {
|
|
318
|
-
"react-doctor/no-fetch-in-effect": "warn",
|
|
319
|
-
"react-doctor/no-derived-state-effect": "warn",
|
|
320
|
-
// ...pick the rules you want
|
|
321
|
-
},
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
The full rule list is in [`oxlint-config.ts`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/oxlint-config.ts).
|
|
326
|
-
|
|
327
|
-
## Scores for popular open-source projects
|
|
328
|
-
|
|
329
|
-
See the live leaderboard at [react.doctor/leaderboard](https://react.doctor/leaderboard) for current scores across React projects.
|
|
330
|
-
|
|
331
|
-
## Contributing
|
|
332
|
-
|
|
333
|
-
Want to contribute? Check out the codebase and submit a PR.
|
|
204
|
+
Looking to contribute back? Clone the repo, install, build, and submit a PR.
|
|
334
205
|
|
|
335
206
|
```bash
|
|
336
207
|
git clone https://github.com/millionco/react-doctor
|
|
337
208
|
cd react-doctor
|
|
338
209
|
pnpm install
|
|
339
210
|
pnpm build
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
Run locally:
|
|
343
|
-
|
|
344
|
-
```bash
|
|
345
211
|
node packages/react-doctor/bin/react-doctor.js /path/to/your/react-project
|
|
346
212
|
```
|
|
347
213
|
|
|
214
|
+
Find a bug? Head to the [issue tracker](https://github.com/millionco/react-doctor/issues).
|
|
215
|
+
|
|
348
216
|
### License
|
|
349
217
|
|
|
350
218
|
React Doctor is MIT-licensed open-source software.
|