Repository Analysis

millionco/react-doctor

Your agent writes bad React. This catches it

1.3 Likely human-written View on GitHub
1.3
Adjusted Score
1.3
Raw Score
100%
Time Factor
2026-05-30
Last Push
11,606
Stars
TypeScript
Language
172,800
Lines of Code
1269
Files
201
Pattern Hits
2026-05-31
Scan Date

Score History

Severity Breakdown

CRITICAL 0HIGH 1MEDIUM 6LOW 194

Pattern Findings

201 matches across 5 categories. Click a row to expand file-level details.

Over-Commented Block165 hits · 165 pts
SeverityFileLineSnippet
LOW…ugin-react-doctor/src/react-native-dependency-names.ts1// Canonical RN-aware-manifest detection rules. Co-located with the rule
LOW…eact-doctor/src/test-utils/attach-parent-references.ts1// Re-exported from the production utility — see
LOW…-plugin-react-doctor/src/plugin/react-doctor-plugin.ts1import { ruleRegistry } from "./rule-registry.js";
LOW…oxlint-plugin-react-doctor/src/plugin/constants/dom.ts21//
LOW…ugin-react-doctor/src/plugin/constants/react-native.ts21 "Heading",
LOW…int-plugin-react-doctor/src/plugin/constants/design.ts41export const TYPOGRAPHY_PUNCTUATION_EXCLUDED_TAG_NAMES = new Set([
LOW…t-plugin-react-doctor/src/plugin/constants/security.ts21// when called as a method (e.g. `analytics.getUser()` is not an auth
LOW…/oxlint-plugin-react-doctor/src/plugin/constants/js.ts61
LOW…/oxlint-plugin-react-doctor/src/plugin/constants/js.ts221// — `findByRole`, `findByText`, etc. Treat any callee whose rightmost
LOW…plugin-react-doctor/src/plugin/constants/thresholds.ts21// caps how many re-export hops the barrel resolver chases before
LOW…lint-plugin-react-doctor/src/plugin/constants/react.ts61// included so the chain root resolves uniformly regardless of how
LOW…lint-plugin-react-doctor/src/plugin/constants/react.ts121 "cleanup",
LOW…lint-plugin-react-doctor/src/plugin/constants/react.ts181 "delete",
LOW…lint-plugin-react-doctor/src/plugin/constants/react.ts201// shorthand in one place propagates to every detector that recognizes it.
LOW…lugin/utils/is-nextjs-metadata-image-route-filename.ts1import path from "node:path";
LOW…t-doctor/src/plugin/utils/classify-package-platform.ts141
LOW…ct-doctor/src/plugin/utils/get-root-identifier-name.ts1import type { EsTreeNode } from "./es-tree-node.js";
LOW…-plugin-react-doctor/src/plugin/utils/rule-visitors.ts1// The handler parameter is intentionally `any` so each rule can declare its
LOW…-react-doctor/src/plugin/utils/is-testlike-filename.ts161 "lint-staged.config.mjs",
LOW…ctor/src/plugin/utils/build-same-file-memo-registry.ts1import { REACT_HOC_NAMES } from "../constants/react.js";
LOW…/src/plugin/utils/is-canonical-react-namespace-name.ts1// Recognises identifier names that conventionally bind to the `react`
LOW…es/oxlint-plugin-react-doctor/src/plugin/utils/rule.ts21 // the rule itself (not its filename or export-variable name) because
LOW…es/oxlint-plugin-react-doctor/src/plugin/utils/rule.ts41 requires?: ReadonlyArray<string>;
LOW…-react-doctor/src/plugin/utils/is-react-native-file.ts1import { classifyPackagePlatform } from "./classify-package-platform.js";
LOW…-react-doctor/src/plugin/utils/is-react-native-file.ts21// given the surrounding `context.settings["react-doctor"].framework` hint.
LOW…c/plugin/utils/collect-react-redux-selector-aliases.ts1import type { EsTreeNode } from "./es-tree-node.js";
LOW…c/plugin/utils/collect-react-redux-selector-aliases.ts21// const useAppSelector = useSelector;
LOW…doctor/src/plugin/utils/find-exported-function-body.ts21// function/arrow node bound to that export, or null if the export
LOW…doctor/src/plugin/utils/find-exported-function-body.ts161 // ImportNamespaceSpecifier: the entire module's namespace. Cannot
LOW…/src/plugin/utils/enclosing-component-or-hook-scope.ts21//
LOW…rc/plugin/utils/create-component-prop-stack-tracker.ts101const isFunctionLikeVariableDeclarator = (node: EsTreeNode): boolean => {
LOW…-doctor/src/plugin/utils/wrap-with-semantic-context.ts21// Performance: each analysis is O(file size). For the average React
LOW…t-doctor/src/plugin/utils/find-variable-initializer.ts1import type { EsTreeNode } from "./es-tree-node.js";
LOW…doctor/src/plugin/utils/get-callee-identifier-trail.ts1import type { EsTreeNode } from "./es-tree-node.js";
LOW…t-plugin-react-doctor/src/plugin/utils/es-tree-node.ts1import type { TSESTree } from "@typescript-eslint/types";
LOW…r/src/plugin/utils/is-inside-platform-os-web-branch.ts121
LOW…r/src/plugin/utils/is-inside-platform-os-web-branch.ts141// Platform.OS === "web" ? <node here /> : …
LOW…r/src/plugin/utils/enclosing-component-or-hook-name.ts1import {
LOW…eact-doctor/src/plugin/utils/wrap-react-native-rule.ts1import { isReactNativeFileActive } from "./is-react-native-file.js";
LOW…gin-react-doctor/src/plugin/semantic/scope-analysis.ts521// Determines whether a BlockStatement should open its own scope. The
LOW…gin-react-doctor/src/plugin/semantic/scope-analysis.ts681 // Special-case structural nodes that open scopes BEFORE they bind
LOW…react-doctor/src/plugin/semantic/control-flow-graph.ts1import type { EsTreeNode } from "../utils/es-tree-node.js";
LOW…react-doctor/src/plugin/semantic/control-flow-graph.ts441 owner: functionNode,
LOW…react-doctor/src/plugin/semantic/control-flow-graph.ts501
LOW…rules/react-native/rn-list-recyclable-without-types.ts1import { defineRule } from "../../utils/define-rule.js";
LOW…es/react-native/rn-list-missing-estimated-item-size.ts1import { defineRule } from "../../utils/define-rule.js";
LOW…ctor/src/plugin/rules/react-builtins/rules-of-hooks.ts141 // Resolution policy mirrors upstream's "use-prefixed names ARE
LOW…doctor/src/plugin/rules/react-builtins/jsx-no-undef.ts41// Port of `oxc_linter::rules::react::jsx_no_undef`. Reports JSX usages
LOW…/rules/react-builtins/only-export-components-tables.ts101 "App.jsx",
LOW…lugin/rules/react-builtins/jsx-no-new-array-as-prop.ts121 walker = walker.parent ?? null;
LOW…lugin/rules/react-builtins/jsx-no-new-array-as-prop.ts161 // memo/forwardRef/observer wrapper), the rule's "React.memo
LOW…src/plugin/rules/react-builtins/no-unknown-property.ts61 `Unknown property — use \`${suggested}\` instead.`;
LOW…/src/plugin/rules/react-builtins/no-array-index-key.ts141 return false;
LOW…/src/plugin/rules/react-builtins/no-array-index-key.ts381 // state to corrupt; reorders just re-diff attributes.
LOW…les/react-builtins/jsx-no-new-object-as-prop-tables.ts1// Object-shape prop names + suffix patterns consumed by the
LOW…es/react-builtins/jsx-no-constructed-context-values.ts121 return binding.scopeOwner.type === "Program";
LOW…/plugin/rules/react-builtins/only-export-components.ts281
LOW…/plugin/rules/react-builtins/only-export-components.ts301// Custom hook files: `useCreateRouter.tsx`, `useTranslation.tsx`,
LOW…/plugin/rules/react-builtins/only-export-components.ts341 }
LOW…tor/src/plugin/rules/react-builtins/forbid-elements.ts61 },
105 more matches not shown…
Hyper-Verbose Identifiers29 hits · 36 pts
SeverityFileLineSnippet
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json24 "code": "\n// Valid because components can call functions.\nfunction ComponentWithNormalFunction() {\n doSomethin
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json27 "code": "\n// Valid because functions can call functions.\nfunction normalFunctionWithNormalFunction() {\n doSome
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json30 "code": "\n// Valid because functions can call functions.\nfunction normalFunctionWithConditionalFunction() {\n i
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json33 "code": "\n// Valid because functions can call functions.\nfunction functionThatStartsWithUseButIsntAHook() {\n i
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json220 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction C
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json265 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction C
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json274 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction c
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json283 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction u
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json292 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction c
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json310 "code": "\n// Invalid because it's a common misunderstanding.\n// We *could* make it valid but the runtime error c
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json319 "code": "\n// Invalid because it's a common misunderstanding.\n// We *could* make it valid but the runtime error c
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json346 "code": "\n// Invalid because it's a common misunderstanding.\n// We *could* make it valid but the runtime error c
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json355 "code": "\n// Invalid because it's a common misunderstanding.\n// We *could* make it valid but the runtime error c
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json364 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction C
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json373 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction C
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json382 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction C
LOW…act-builtins/__upstream-fixtures__/rules-of-hooks.json421 "code": "\n// Invalid because it's dangerous and might not warn otherwise.\n// This *must* be invalid.\nfunction n
LOW…react-builtins/__fixtures__/rules-of-hooks.fixtures.ts229 function ComponentWithHookInsideLoop() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts593 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts608 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts653 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts668 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts683 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts698 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts816 function UnstableNestedFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts833 function UnstableNestedClassComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts884 function NestedUnstableFunctionComponent() {
LOW…__fixtures__/no-unstable-nested-components.fixtures.ts903 function NestedUnstableFunctionComponent() {
LOW…tor/tests/regressions/react-19-migration-rules.test.ts157export function componentWillReceiveProps() {}
AI Slop Vocabulary3 hits · 9 pts
SeverityFileLineSnippet
MEDIUM…c/plugin/rules/js-performance/js-combine-iterations.ts118// contains "TSTypePredicate" — robust against AST shape variance.
MEDIUM…src/plugin/rules/architecture/no-legacy-context-api.ts14// is high-leverage. We catch the static class-property forms AND the
MEDIUMpackages/core/src/constants.ts168// the underlying engine is robust. The wildcard cap intentionally
Decorative Section Separators3 hits · 9 pts
SeverityFileLineSnippet
MEDIUMpackages/core/src/run-inspect.ts256 // ── Phase: environment checks ──────────────────────────────────
MEDIUMpackages/core/src/types/inspect.ts42 // ── Engine inputs ────────────────────────────────────────────────
MEDIUMpackages/core/src/types/inspect.ts50 // ── Rendering / orchestration knobs ──────────────────────────────
Cross-Language Confusion1 hit · 5 pts
SeverityFileLineSnippet
HIGHscripts/smoke-tty-prompt.py119 handle.write("export const Component = () => null;\n")