# How React‑Doctor Handles Scanning in a Monorepo with Multiple Projects

> Learn how React Doctor scans monorepos with multiple projects by automatically detecting roots, selecting projects, and unifying diagnostics across all subprojects.

- Repository: [Million Software, Inc./react-doctor](https://github.com/millionco/react-doctor)
- Tags: how-to-guide
- Published: 2026-05-12

---

**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`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/utils/find-monorepo-root.ts). This utility walks upward from the invocation directory searching for workspace marker files:

- [`pnpm-workspace.yaml`](https://github.com/millionco/react-doctor/blob/main/pnpm-workspace.yaml)
- [`nx.json`](https://github.com/millionco/react-doctor/blob/main/nx.json)
- [`package.json`](https://github.com/millionco/react-doctor/blob/main/package.json) containing a `workspaces` field

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`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/utils/select-projects.ts)) determines which directories to analyze. The function implements a cascading resolution strategy.

1. **Workspace Package Enumeration** – It first attempts `listWorkspacePackages` to read the workspace manifest and list all defined packages.
2. **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 a `src` directory with `.tsx` files).

### 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`](https://github.com/millionco/react-doctor/blob/main/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`](https://github.com/millionco/react-doctor/blob/main/select-projects.ts)):

```bash
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`](https://github.com/millionco/react-doctor/blob/main/select-projects.ts)):

```bash
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`](https://github.com/millionco/react-doctor/blob/main/select-projects.ts)).

## Executing the Scan Across Projects

The CLI entry point ([`src/cli.ts`](https://github.com/millionco/react-doctor/blob/main/src/cli.ts)) orchestrates the final execution flow. It passes the array of selected directories to the core scanner ([`src/scan.ts`](https://github.com/millionco/react-doctor/blob/main/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`](https://github.com/millionco/react-doctor/blob/main/select-projects.ts)).

## Programmatic Usage

You can leverage the project selection logic directly in Node.js scripts:

```typescript
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**: `findMonorepoRoot` identifies the repository base by searching for [`pnpm-workspace.yaml`](https://github.com/millionco/react-doctor/blob/main/pnpm-workspace.yaml), [`nx.json`](https://github.com/millionco/react-doctor/blob/main/nx.json), or [`package.json`](https://github.com/millionco/react-doctor/blob/main/package.json) workspace definitions in [`packages/react-doctor/src/utils/find-monorepo-root.ts`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/utils/find-monorepo-root.ts).
- **Project Selection**: `selectProjects` resolves targets via workspace manifests, filesystem discovery, CLI flags, or interactive prompts in [`packages/react-doctor/src/utils/select-projects.ts`](https://github.com/millionco/react-doctor/blob/main/packages/react-doctor/src/utils/select-projects.ts).
- **Flag Support**: Use `--project` to filter specific packages and `--skip-prompts` for headless CI execution.
- **Unified Reporting**: The scanner in [`src/scan.ts`](https://github.com/millionco/react-doctor/blob/main/src/scan.ts) iterates 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`](https://github.com/millionco/react-doctor/blob/main/pnpm-workspace.yaml), [`nx.json`](https://github.com/millionco/react-doctor/blob/main/nx.json), or the `workspaces` field in [`package.json`](https://github.com/millionco/react-doctor/blob/main/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.