It depends on the package manager. npm and Yarn declare workspaces in a workspaces array in the root package.json. pnpm requires a pnpm-workspace.yaml at the root and reads only that file. A scanner that reads the wrong one will miss packages or invent them.
Where each tool looks
Yarn's documentation says to add a workspaces array to the root package.json and list relative glob patterns for the folders, for example packages followed by a star. Every subdirectory that matches becomes a workspace.
pnpm is stricter. Its docs state that a workspace must have a pnpm-workspace.yaml file in its root, with project locations listed under packages. If a repository already uses the workspaces field from npm, Yarn or Bun, pnpm install creates the yaml file with the same patterns and never overwrites an existing one. If the two later diverge, pnpm warns, because only pnpm-workspace.yaml is read.
| Package manager | Workspace declaration | Read by pnpm? |
|---|---|---|
| npm | workspaces in package.json | No, ignored by pnpm |
| Yarn | workspaces in package.json | No, ignored by pnpm |
| pnpm | pnpm-workspace.yaml | Yes |
Why this causes scan problems
Imagine a repo that migrated from Yarn to pnpm two years ago. The root package.json still lists ten folders. The yaml file lists twelve. A tool that trusts package.json reports ten packages. Your install uses twelve. Two packages are never scanned, and nobody sees an error.
The opposite also happens. A folder named in the old field may no longer be a workspace at all, so a scan reports results for code that is not part of the build.
How to check in one minute
- Find the package manager. Look for the lockfile name at the root, then check for a packageManager field in package.json.
- Read the one workspace declaration that manager actually uses.
- List every package.json in the tree and compare.
git ls-files '*package.json'
Any manifest that is not covered by the declared globs is either a deliberate exclusion or a gap. Decide which, and write it down.
Make detection explicit in CI
Do not rely on a scanner to guess. Pass it the list of package directories you derived, or run the scan from the root and check the reported project count against your own list. A mismatch should fail the job. That turns a silent miss into a visible one.
Also watch for nested workspaces, where a subfolder has its own workspace config. Most tools do not merge those with the root config, so treat each as its own scan root.
Safeguard scans dependencies and generates SBOMs per project, so it works from whatever package directories you give it. The free scan at https://gold.safeguard.sh/scan is a quick way to try one package.
Quick check
Does pnpm read the workspaces field in package.json?
No. Its docs say only pnpm-workspace.yaml is read, and pnpm warns if the two diverge.
What is a quick sign of a missed package?
A manifest in the tree that matches no declared workspace glob and has no lockfile above it.
Sources
Last reviewed: 19 October 2026.