|
1 | 1 | --- |
2 | 2 | name: react-doctor |
3 | | -description: Diagnose and fix React codebase health issues. Use when reviewing React code, fixing performance problems, auditing security, or improving code quality. Run react-doctor to scan for issues, then fix them. |
| 3 | +description: Diagnose and fix React codebase health issues. Use when reviewing React code, fixing performance problems, auditing security, or improving code quality. |
4 | 4 | version: 1.0.0 |
5 | 5 | --- |
6 | 6 |
|
7 | 7 | # React Doctor |
8 | 8 |
|
9 | | -A CLI that audits your React codebase for security, performance, correctness, and architecture issues, then outputs a 0-100 score with actionable diagnostics. |
| 9 | +Scans your React codebase for security, performance, correctness, and architecture issues. Outputs a 0-100 score with actionable diagnostics. |
10 | 10 |
|
11 | | -## When to Use |
12 | | - |
13 | | -- When reviewing or auditing React code |
14 | | -- When fixing performance, security, or correctness issues |
15 | | -- When a user asks to improve their React codebase health |
16 | | -- When onboarding to a new React project to find existing problems |
17 | | -- After making large changes to verify nothing regressed |
18 | | - |
19 | | -## How to Run |
20 | | - |
21 | | -Run this command at the project root: |
22 | | - |
23 | | -```bash |
24 | | -npx -y react-doctor@latest . |
25 | | -``` |
26 | | - |
27 | | -Use `--verbose` to see affected files and line numbers: |
| 11 | +## Usage |
28 | 12 |
|
29 | 13 | ```bash |
30 | 14 | npx -y react-doctor@latest . --verbose |
31 | 15 | ``` |
32 | 16 |
|
33 | | -Use `--fix` to open Ami and auto-fix all issues: |
34 | | - |
35 | | -```bash |
36 | | -npx -y react-doctor@latest . --fix |
37 | | -``` |
38 | | - |
39 | | -## What It Checks |
40 | | - |
41 | | -React Doctor runs 47+ rules across these categories: |
42 | | - |
43 | | -### Security |
44 | | - |
45 | | -- Hardcoded secrets exposed to client bundle (API keys, tokens) |
46 | | -- eval() and dynamic code execution risks |
47 | | - |
48 | | -### State & Effects |
49 | | - |
50 | | -- Derived state computed in useEffect (should compute during render) |
51 | | -- Data fetched in useEffect without cleanup (race conditions) |
52 | | -- useState initialized from prop (should derive during render) |
53 | | -- Cascading setState calls in useEffect |
54 | | -- Missing lazy initialization for expensive useState |
55 | | -- Stale closures in setState updates |
56 | | - |
57 | | -### Architecture |
58 | | - |
59 | | -- Components defined inside other components (destroys state every render) |
60 | | -- Giant components that should be split |
61 | | -- Inline render functions (breaks reconciliation) |
62 | | -- Non-descriptive event handler names |
63 | | - |
64 | | -### Performance |
65 | | - |
66 | | -- Animating layout properties (width, height, top, left) instead of transform |
67 | | -- transition-all causing unnecessary repaints |
68 | | -- Large animated blur values exceeding GPU memory on mobile |
69 | | -- useMemo on simple expressions (unnecessary overhead) |
70 | | - |
71 | | -### Correctness |
72 | | - |
73 | | -- Array index used as key (causes bugs when items are reordered) |
74 | | -- Conditional rendering bugs |
75 | | - |
76 | | -### Next.js |
77 | | - |
78 | | -- Missing metadata or generateMetadata export (hurts SEO) |
79 | | -- Client-side fetching for server data |
80 | | -- Async client components (not supported) |
81 | | -- Using `<img>` instead of `next/image` |
82 | | -- Using `<a>` instead of `next/link` |
83 | | -- redirect() inside try-catch (throws internally) |
84 | | - |
85 | | -### Bundle Size |
86 | | - |
87 | | -- Barrel file imports bloating bundles |
88 | | -- Full lodash imports instead of individual functions |
89 | | -- moment.js (300kb+, use date-fns or dayjs) |
90 | | -- Heavy libraries without code splitting |
91 | | - |
92 | | -### Server |
93 | | - |
94 | | -- Server actions missing authentication checks |
95 | | -- Blocking operations that should use after() |
96 | | - |
97 | | -### Accessibility |
98 | | - |
99 | | -- Missing prefers-reduced-motion checks for animations |
100 | | - |
101 | | -### Dead Code |
102 | | - |
103 | | -- Unused files, exports, types, and duplicate exports |
104 | | - |
105 | 17 | ## Workflow |
106 | 18 |
|
107 | | -1. Run `npx -y react-doctor@latest . --verbose` to scan the codebase |
108 | | -2. Read every diagnostic, noting the file paths and line numbers |
109 | | -3. Fix issues one by one, starting with errors (highest severity) |
110 | | -4. Re-run react-doctor to verify the score improved |
111 | | -5. Repeat until the score is above 75 (Great) |
112 | | - |
113 | | -## Interpreting the Score |
114 | | - |
115 | | -| Score | Label | Meaning | |
116 | | -| ------ | ---------- | -------------------------------------------------- | |
117 | | -| 75-100 | Great | Codebase follows React best practices | |
118 | | -| 50-74 | Needs work | Several issues that should be addressed | |
119 | | -| 0-49 | Critical | Significant problems that need immediate attention | |
| 19 | +1. Run the command above at the project root |
| 20 | +2. Read every diagnostic with file paths and line numbers |
| 21 | +3. Fix issues starting with errors (highest severity) |
| 22 | +4. Re-run to verify the score improved |
| 23 | + |
| 24 | +## Rules (47+) |
| 25 | + |
| 26 | +- **Security**: hardcoded secrets in client bundle, eval() |
| 27 | +- **State & Effects**: derived state in useEffect, missing cleanup, useState from props, cascading setState |
| 28 | +- **Architecture**: components inside components, giant components, inline render functions |
| 29 | +- **Performance**: layout property animations, transition-all, large blur values |
| 30 | +- **Correctness**: array index as key, conditional rendering bugs |
| 31 | +- **Next.js**: missing metadata, client-side fetching for server data, async client components |
| 32 | +- **Bundle Size**: barrel imports, full lodash, moment.js, missing code splitting |
| 33 | +- **Server**: missing auth in server actions, blocking without after() |
| 34 | +- **Accessibility**: missing prefers-reduced-motion |
| 35 | +- **Dead Code**: unused files, exports, types |
| 36 | + |
| 37 | +## Score |
| 38 | + |
| 39 | +- **75+**: Great |
| 40 | +- **50-74**: Needs work |
| 41 | +- **0-49**: Critical |
0 commit comments