Skip to content

proda-ai/react-doctor

 
 

Repository files navigation

React Doctor

@proda-ai/react-doctor

This is a Proda fork of millionco/react-doctor.

Why this fork exists

React Doctor has hardcoded thresholds (e.g. 300 lines for no-giant-component) with no way to configure them per-directory or per-rule. The upstream config only supports globally ignoring rules or files — there is no middle ground.

We needed:

  • Per-directory threshold overrides — view components are naturally larger than leaf components, and a single global limit doesn't fit both
  • Bug fixes not yet released upstream (e.g. #113 — non-existent jsx-a11y/no-noninteractive-element-interactions rule breaking the score)

This fork is published as @proda-ai/react-doctor on GitHub Packages. Upstream contributions are welcome and will be submitted back when possible.

What's different from upstream

Change Status
Remove non-existent jsx-a11y/no-noninteractive-element-interactions rule (#113) ✅ Merged
Configurable per-directory thresholds via react-doctor.config.json 🔜 On branch feat/configurable-thresholds

Configurable thresholds (planned)

{
  "thresholds": {
    "component-lines": {
      "default": 300,
      "overrides": [{ "files": ["src/ui/views/**"], "max": 400 }]
    }
  }
}

Versioning

Versions follow {upstream}-proda.{N}:

Version Meaning
0.0.30-proda.1 Based on upstream 0.0.30, Proda patch 1
0.0.30-proda.2 Same upstream base, next Proda change
0.0.31-proda.1 After merging upstream 0.0.31, first Proda patch

The version is set manually in packages/react-doctor/package.json as part of the PR. Bump the proda.N suffix when making changes.

CI / CD

On pull requests

  • CI / test — runs tests, lint, and format checks (upstream workflow)
  • Version check — if package.json was changed, verifies the version doesn't already exist in GitHub Packages. Fails with a clear message if you forgot to bump

On merge to main

  • Publish — builds with Node 24, verifies the version is new (safety net), and publishes @proda-ai/react-doctor to GitHub Packages. No manual steps needed

How to release a new version

  1. Make your changes in a PR
  2. Bump the version in packages/react-doctor/package.json (increment the proda.N suffix)
  3. CI validates the version is available
  4. Merge — package is published automatically

Syncing with upstream

  1. git fetch upstream && git merge upstream/main
  2. Update the base version to match upstream (e.g. 0.0.31-proda.1)
  3. Resolve conflicts if any, open a PR

Original README follows below.


Let coding agents diagnose and fix your React code.

One command scans your codebase for security, performance, correctness, and architecture issues, then outputs a 0–100 score with actionable diagnostics.

Main.mp4

How it works

React Doctor detects your framework (Next.js, Vite, Remix, etc.), React version, and compiler setup, then runs two analysis passes in parallel:

  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.
  2. Dead code: Detects unused files, exports, types, and duplicates.

Diagnostics are filtered through your config, then scored by severity (errors weigh more than warnings) to produce a 0–100 health score (75+ Great, 50–74 Needs work, <50 Critical).

Install

Run this at your project root:

npx -y react-doctor@latest .

Use --verbose to see affected files and line numbers:

npx -y react-doctor@latest . --verbose

Install for your coding agent

Teach your coding agent all 47+ React best practice rules:

curl -fsSL https://react.doctor/install-skill.sh | bash

Supports Cursor, Claude Code, Amp Code, Codex, Gemini CLI, OpenCode, Windsurf, and Antigravity.

GitHub Actions

- uses: actions/checkout@v5
  with:
    fetch-depth: 0 # required for --diff
- uses: millionco/react-doctor@main
  with:
    diff: main
    github-token: ${{ secrets.GITHUB_TOKEN }}
Input Default Description
directory . Project directory to scan
verbose true Show file details per rule
project Workspace project(s) to scan (comma-separated)
diff Base branch for diff mode. Only changed files are scanned
github-token When set on pull_request events, posts findings as a PR comment
node-version 20 Node.js version to use

The action outputs a score (0–100) you can use in subsequent steps.

Options

Usage: react-doctor [directory] [options]

Options:
  -v, --version     display the version number
  --no-lint         skip linting
  --no-dead-code    skip dead code detection
  --verbose         show file details per rule
  --score           output only the score
  -y, --yes         skip prompts, scan all workspace projects
  --project <name>  select workspace project (comma-separated for multiple)
  --diff [base]     scan only files changed vs base branch
  --ami             enable Ami-related prompts
  --fix             open Ami to auto-fix all issues
  -h, --help        display help for command

Configuration

Create a react-doctor.config.json in your project root to customize behavior:

{
  "ignore": {
    "rules": ["react/no-danger", "jsx-a11y/no-autofocus", "knip/exports"],
    "files": ["src/generated/**"]
  }
}

You can also use the "reactDoctor" key in your package.json instead:

{
  "reactDoctor": {
    "ignore": {
      "rules": ["react/no-danger"]
    }
  }
}

If both exist, react-doctor.config.json takes precedence.

Config options

Key Type Default Description
ignore.rules string[] [] Rules to suppress, using the plugin/rule format shown in diagnostic output (e.g. react/no-danger, knip/exports, knip/types)
ignore.files string[] [] File paths to exclude, supports glob patterns (src/generated/**, **/*.test.tsx)
lint boolean true Enable/disable lint checks (same as --no-lint)
deadCode boolean true Enable/disable dead code detection (same as --no-dead-code)
verbose boolean false Show file details per rule (same as --verbose)
diff boolean | string Force diff mode (true) or pin a base branch ("main"). Set to false to disable auto-detection.

CLI flags always override config values.

Node.js API

You can also use React Doctor programmatically:

import { diagnose } from "react-doctor/api";

const result = await diagnose("./path/to/your/react-project");

console.log(result.score); // { score: 82, label: "Good" } or null
console.log(result.diagnostics); // Array of Diagnostic objects
console.log(result.project); // Detected framework, React version, etc.

The diagnose function accepts an optional second argument:

const result = await diagnose(".", {
  lint: true, // run lint checks (default: true)
  deadCode: true, // run dead code detection (default: true)
});

Each diagnostic has the following shape:

interface Diagnostic {
  filePath: string;
  plugin: string;
  rule: string;
  severity: "error" | "warning";
  message: string;
  help: string;
  line: number;
  column: number;
  category: string;
}
Project Score Share
tldraw 84 view
excalidraw 84 view
twenty 78 view
plane 78 view
formbricks 75 view
posthog 72 view
supabase 69 view
onlook 69 view
payload 68 view
sentry 64 view
cal.com 63 view
dub 62 view

Contributing

Want to contribute? Check out the codebase and submit a PR.

git clone https://github.com/millionco/react-doctor
cd react-doctor
pnpm install
pnpm -r run build

Run locally:

node packages/react-doctor/dist/cli.js /path/to/your/react-project

License

React Doctor is MIT-licensed open-source software.

About

Let coding agents diagnose and fix your React code

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 98.4%
  • Shell 1.5%
  • Other 0.1%