React Doctor
React / Next.js / Vite / React Native 向けのヘルス診断。Oxlint ベースのルールと Knip によるデッドコード検出で 0〜100 のスコアを出す(millionco/react-doctor)。
プロジェクトルートで 1 コマンド走らせると、状態管理・副作用・パフォーマンス・アーキテクチャ・セキュリティ・アクセシビリティ・デッドコードなど横断の診断がまとまり、0〜100 のヘルススコアと修正可能なメッセージが返る。フレームワークと React のメジャーバージョンに応じてルールが自動で切り替わる。
デモとリーダーボードは react.doctor。npm パッケージ名は react-doctor。
リポジトリのルートで次を実行する。結果にスコアと上位のルール違反が表示される。
npx -y react-doctor@latest ..oxlintrc.json や .eslintrc.json がある場合、そのルールがスキャンにマージされスコアに反映される。マージを止めたい場合は設定で adoptExistingLintConfig: false。
コーディングエージェント向けにベストプラクティス用スキルを配置する対話フローがある。Claude Code、Cursor、Codex、OpenCode など検出されたエージェントを選べる。--yes でプロンプトを省略できる。
npx -y react-doctor@latest installpull_request で github-token を渡すと、指摘を PR コメントとして投稿できる。diff に基づく部分スキャンでは履歴取得のため fetch-depth: 0 が推奨される。
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: millionco/react-doctor@main
with:
diff: main
github-token: ${{ secrets.GITHUB_TOKEN }}アクションは score 出力も公開するため、後続ステップの条件に使える。
ルートに JSON を置くか、package.json の "reactDoctor" キーで同様の構造を書ける。CLI フラグは常に設定より優先する。
{
"ignore": {
"rules": ["react/no-danger", "jsx-a11y/no-autofocus"],
"files": ["src/generated/**"],
"overrides": [
{
"files": ["components/diff/**"],
"rules": ["react-doctor/no-array-index-as-key"]
}
]
}
}無視の階層
| キー | 効果 |
|---|---|
ignore.rules | 指定ルールを全体で無効化 |
ignore.files | マッチしたファイル上のすべてのルールを無効化 |
ignore.overrides | ディレクトリごとに特定ルールだけ無効化 |
.gitignore、.eslintignore、.oxlintignore、.prettierignore、および .gitattributes の linguist-vendored / linguist-generated を尊重する。行コメントの // eslint-disable* と // oxlint-disable* も解釈される。
インライン抑制(React Doctor 用)
// react-doctor-disable-next-line react-doctor/no-cascading-set-state
useEffect(() => {
setA(value);
setB(value);
}, [value]);同一行で複数ルールを止めるときはルール ID をカンマ区切り。JSX 内ではブロックコメントや JSX コメントの置き方が ESLint と同様の慣習に合わせる。
同じルールセットが Oxlint プラグインと ESLint フラット設定用プラグインの両方として提供される。既存の Lint パイプラインに組み込みたい場合はこちらを使う。
Oxlint(.oxlintrc.json)
{
"jsPlugins": [{ "name": "react-doctor", "specifier": "react-doctor/oxlint-plugin" }],
"rules": {
"react-doctor/no-fetch-in-effect": "warn",
"react-doctor/no-derived-state-effect": "warn"
}
}ESLint(flat config)
import reactDoctor from "react-doctor/eslint-plugin";
export default [
reactDoctor.configs.recommended,
reactDoctor.configs.next,
reactDoctor.configs["react-native"],
reactDoctor.configs["tanstack-start"],
reactDoctor.configs["tanstack-query"],
];全ルール一覧の実体は upstream の oxlint-config.ts を参照。
| フラグ | 説明 |
|---|---|
--no-lint | Lint をスキップ |
--no-dead-code | デッドコード検出をスキップ |
--diff [base] | 指定ブランチとの差分ファイルだけスキャン |
--staged | ステージ済みファイルのみ(pre-commit 向け) |
--json | 構造化 JSON を標準出力(人可読ログは抑制) |
--explain <file:line> | その位置でルールが発火した理由や抑制が効かない理由を表示 |
--annotations | GitHub Actions のアノテーション形式で診断を出力 |
--fail-on <level> | error / warning / none で終了コードを制御 |
Node API
import { diagnose, toJsonReport, summarizeDiagnostics } from "react-doctor/api";
const result = await diagnose("./path/to/your/react-project");
console.log(result.score);
console.log(result.diagnostics);diagnose の第 2 引数で { lint?: boolean, deadCode?: boolean } を渡せる。toJsonReport と summarizeDiagnostics で JSON レポート用の組み立てができる。型定義は api.ts。
pnpm workspace と Turborepo で管理されている。CLI とルール実装の本体、公開サイト、エージェント向けスキル定義が分離されている。
| 領域 | 役割 |
|---|---|
packages/react-doctor | CLI バイナリ、Oxlint/ESLint プラグイン、スキャン・スコアリング・設定読み込みの中核 |
packages/website | スコア共有やバッジなどの Web 面(Next 系) |
skills/react-doctor | エージェント向けに配布するスキルメタデータ |
action.yml | GitHub Action のエントリ |
pnpm install と pnpm build。ローカルバイナリは node packages/react-doctor/bin/react-doctor.js <path> で試せる。
- GitHub: millionco/react-doctor
- npm: react-doctor
- デモサイト
- リーダーボード(ベンチマークリポジトリ由来の自動更新)
- Issue トラッカー
ライセンス
MIT。