Choosing Between pnpm Default and Strict Mode for Monorepo Dependency Safety
A decision guide that compares pnpm's default and strict modes, outlines constraints, and shows how to enable and validate strict mode in a workspace.
12 Dec 2025, 05:30 UTC

Decision and constraints
Enable pnpm strict mode to enforce that only packages listed in dependencies or devDependencies can be imported, preventing accidental reliance on transitive packages.
Constraints to consider before switching:
- Requires pnpm v6.0 or newer.
- All projects in the workspace must use the same lockfile version (v6+).
- CI pipelines should run
pnpm install --frozen-lockfileto avoid lockfile drift.
Options comparison
| Mode | Description | Pros | Cons |
|---|---|---|---|
| Default (non‑strict) | Allows any package present in node_modules to be required. |
Simple setup; works with legacy packages that rely on implicit transitive imports. | Risk of hidden dependencies; harder to upgrade safely; builds may be nondeterministic. |
Strict (enabled via strict-peer-deps) |
Enforces that imports match declared dependencies or devDependencies. |
Guarantees an explicit dependency graph; safer refactors and more reproducible builds. | May break code that currently uses undeclared transitive imports; requires package.json updates before enabling. |
Trade‑offs
Strict mode improves reproducibility and reduces surprise failures caused by hidden dependencies. The downside is an initial refactor cost: any file that imports a package not listed in its manifest will fail to build. Default mode is easier to adopt immediately but can lead to version conflicts and nondeterministic CI results over time.
Implementation and validation
Add the strict‑peer‑deps setting to the workspace configuration. You can place it in either
.npmrcat the workspace root or inpnpm-workspace.yaml:# .npmrc strict-peer-deps=trueor
# pnpm-workspace.yaml packages: - '**' npm_config_strict_peer_deps: trueRun this edit with write access to the repository root.
Install dependencies with a frozen lockfile to ensure the setting is applied:
# Run in the workspace root (requires read/write on node_modules) pnpm install --frozen-lockfileValidate that the mode is active:
- Check the config:
pnpm config get strict-peer-depsshould outputtrue. - Attempt to import an undeclared package. For example, create a test file
packages/pkg-b/test.jsthat contains:
// test.js const undeclared = require('some-package-not-in-pkg-b'); console.log(undeclared);Run
pnpm --filter pkg-b run node test.js(or execute the file directly). With strict mode enabled the command should fail with an error similar to:Error: Cannot find module 'some-package-not-in-pkg-b'If the import succeeds, strict mode is not being enforced; verify the config and lockfile version.
- Check the config:
Optional: detect missing declarations before enabling strict mode:
# Lists packages that are imported but not declared pnpm ls --unusedReview the output and add any missing entries to the relevant
package.jsonfiles.
Limitations and practical checks
Strict mode only validates peer dependencies when the flag is on; it does not block access to regular transitive dependencies unless those are also listed in dependencies or devDependencies. Therefore, after enabling the mode you should still:
- Run
pnpm ls --unusedperiodically to catch newly introduced undeclared imports. - Ensure CI runs
pnpm install --frozen-lockfileso the lockfile cannot drift and re‑introduce hidden dependencies.
To confirm the setting persists across machines, check the config in any clone:
pnpm config get strict-peer-deps
If the output is false, the mode is not active and you must reapply the configuration.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.