How React‑Doctor Handles Scanning in a Monorepo with Multiple Projects
React‑Doctor automatically detects monorepo roots, enumerates workspace packages or filesystem projects, and aggregates diagnostics across all sub‑projects using a pipeline of root detection, project selection, and unified scanning.
React‑Doctor—an open‑source diagnostic tool from the millionco/react-doctor repository—is engineered to analyze React codebases within complex monorepo architectures. Whether your repository uses PNPM workspaces, Nx, or a custom folder layout, the CLI discovers all constituent projects and generates a consolidated health report. Understanding how react‑doctor monorepo scanning works enables teams to integrate precise health checks into CI pipelines and local development workflows.
Detecting the Monorepo Root
The scanning process begins with findMonorepoRoot, located in packages/react-doctor/src/utils/find-monorepo-root.ts. This utility walks upward from the invocation directory searching for workspace marker files:
pnpm-workspace.yamlnx.jsonpackage.jsoncontaining aworkspacesfield
When any of these markers are found, the containing directory is designated as the monorepo root. This detection mechanism allows React‑Doctor to establish the correct base path for resolving relative package locations and configuration files.
Selecting Projects to Scan
Once the root is identified, selectProjects (packages/react-doctor/src/utils/select-projects.ts) determines which directories to analyze. The function implements a cascading resolution strategy.
- Workspace Package Enumeration – It first attempts
listWorkspacePackagesto read the workspace manifest and list all defined packages. - Filesystem Discovery – If no workspace packages are found, it falls back to
discoverReactSubprojects, which traverses the directory tree seeking folders containing React entry points (typically asrcdirectory with.tsxfiles).
Targeting Specific Packages with --project
Users can bypass automatic discovery by passing the --project flag followed by a comma‑separated list of package names. React‑Doctor resolves these names against discovered packages, matching either the package.json name or the folder basename. If a specified name does not exist, the CLI throws an explicit error listing all available projects (lines 36‑56 in select-projects.ts):
npx react-doctor --project ui,admin
Non‑Interactive CI Mode with --skip-prompts
For automated environments, the --skip-prompts flag instructs React‑Doctor to print discovered projects and scan every one without user intervention (lines 28‑31 in select-projects.ts):
npx react-doctor --skip-prompts
Interactive Multiselect Prompts
When multiple packages exist and no overriding flags are provided, React‑Doctor displays an interactive multiselect prompt using the prompts library. Each option shows the package name alongside its relative path from the monorepo root, allowing developers to cherry‑pick specific projects for analysis (lines 69‑84 in select-projects.ts).
Executing the Scan Across Projects
The CLI entry point (src/cli.ts) orchestrates the final execution flow. It passes the array of selected directories to the core scanner (src/scan.ts), which performs the following for each project:
- Loads project‑specific lint configurations
- Executes underlying tools (Oxlint, Knip, etc.)
- Aggregates diagnostics into a unified report
The final output combines results from every selected directory, presenting a holistic view of the monorepo’s health.
Fallback Behavior
If React‑Doctor fails to detect workspace packages or sub‑projects, it treats the current working directory as a single standalone project and proceeds with the scan (lines 18‑19 in select-projects.ts).
Programmatic Usage
You can leverage the project selection logic directly in Node.js scripts:
import { selectProjects } from 'react-doctor';
const root = '/path/to/monorepo';
const projects = await selectProjects(root, undefined, true);
// projects is an array of absolute directories ready for the scanner
This pattern is useful for building custom automation that preprocesses the project list before invoking the scan routine.
Summary
- Root Detection:
findMonorepoRootidentifies the repository base by searching forpnpm-workspace.yaml,nx.json, orpackage.jsonworkspace definitions inpackages/react-doctor/src/utils/find-monorepo-root.ts. - Project Selection:
selectProjectsresolves targets via workspace manifests, filesystem discovery, CLI flags, or interactive prompts inpackages/react-doctor/src/utils/select-projects.ts. - Flag Support: Use
--projectto filter specific packages and--skip-promptsfor headless CI execution. - Unified Reporting: The scanner in
src/scan.tsiterates over selected directories and merges diagnostics into a single comprehensive report.
Frequently Asked Questions
How does React‑Doctor identify which packages belong to a monorepo?
React‑Doctor attempts to read workspace configuration files such as pnpm-workspace.yaml, nx.json, or the workspaces field in package.json. If formal workspace metadata is absent, it executes discoverReactSubprojects to locate directories containing React source files (.tsx entries), ensuring compatibility with both structured and ad‑hoc monorepo layouts.
Can I scan only specific applications in a large monorepo?
Yes. Pass the --project flag with a comma‑separated list of package names or folder basenames. React‑Doctor validates these against discovered projects and restricts the scan to matching directories, throwing an error if a name cannot be found.
Is React‑Doctor suitable for CI/CD pipelines in monorepos?
Absolutely. The --skip-prompts flag disables interactive selection and automatically scans all discovered projects. This mode is designed for continuous integration environments where human input is unavailable, ensuring consistent automated health checks across the repository.
What happens if React‑Doctor cannot find any workspace configuration?
If neither workspace packages nor React sub‑projects are detected, React‑Doctor defaults to treating the current directory as a single project. It proceeds to scan that directory directly, making the tool functional for both monorepos and standalone React applications without configuration changes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →