Reproduction
In a pnpm workspace where react is declared only in the root package.json (a common hoisting pattern), running react-doctor against a sub-package fails:
my-monorepo/
├── package.json
├── pnpm-workspace.yaml
└── apps/
└── web/
└── package.json
From apps/web:
$ npx react-doctor@latest .
react-doctor v0.2.1
No React dependency found in apps/web/package.json. Add "react" to dependencies (or peerDependencies) and re-run.
Why this is a problem
Workspace hoisting is the recommended setup for pnpm (default), yarn (nohoist unset), and npm workspaces. It guarantees a single React version across all apps and is widely used — Turborepo defaults to this layout, Next.js docs recommend it for multi-app setups. The current check forces every workspace app to redeclare react, duplicating dependency state and creating drift risk between the root's pinned version and the app's restated one.
Suggested fix
When react is not in the local package.json, fall back to - Walk up to find workspace root (pnpm-workspace.yaml, the workspaces field in a parent package.json, or lerna.json) and check root deps too.
Reproduction
In a pnpm workspace where
reactis declared only in the rootpackage.json(a common hoisting pattern), runningreact-doctoragainst a sub-package fails:From
apps/web:$ npx react-doctor@latest .
react-doctor v0.2.1
No React dependency found in apps/web/package.json. Add "react" to dependencies (or peerDependencies) and re-run.
Why this is a problem
Workspace hoisting is the recommended setup for pnpm (default), yarn (
nohoistunset), and npm workspaces. It guarantees a single React version across all apps and is widely used — Turborepo defaults to this layout, Next.js docs recommend it for multi-app setups. The current check forces every workspace app to redeclarereact, duplicating dependency state and creating drift risk between the root's pinned version and the app's restated one.Suggested fix
When
reactis not in the localpackage.json, fall back to - Walk up to find workspace root (pnpm-workspace.yaml, theworkspacesfield in a parentpackage.json, orlerna.json) and check root deps too.