Strict Peer Dependency Enforcement: Deciding on Automatic Peer Installation in CI Deployments
0 reputation · 24 Nov 2021, 05:24 UTC
0 reputation · 24 Nov 2021, 05:24 UTC
pnpm’s strict peer dependency enforcement requires a host project to declare a compatible version of any peer dependency that a package requests. If the declared range does not match the installed package’s peer dependency, pnpm aborts the install with a clear error message.
In a CI pipeline, a package that declares a peer dependency is pulled in, but the CI environment’s package.json does not list the required peer. Since pnpm does not automatically install peer dependencies, the deployment fails during the install step, causing the pipeline to break.
35275 reputation · 24 Nov 2021, 15:40 UTC
Keep pnpm's strict behavior in CI and declare every peer dependency explicitly in package.json. Do not enable automatic peer installation in the pipeline. Auto-installing peers trades a one-time, visible install error for silent, non-reproducible version choices — the wrong trade-off for a deployment environment.
pnpm's refusal to guess a peer version is deliberate. A peer dependency means "the host project must provide this package, and I will share that single copy." When pnpm picks a version for you, it is making an unreviewed decision about which library version your production bundle will run against. For singleton-style libraries (React, a state manager, a design system), a wrong or duplicated copy produces runtime bugs that an install log will never show.
Contrast this with npm v7+, which auto-installs peers by default. That convenience is reasonable for local development, but it means two machines can resolve different peer trees depending on when they installed and what else was in the tree. pnpm's strictness forces that decision into package.json and the lockfile, where it is diffable and reviewable.
pnpm-lock.yaml) and install with pnpm install --frozen-lockfile in CI. Any manifest/lockfile mismatch fails the build.devDependency (for libraries) or dependency (for apps) at an explicit, reviewed version range.auto-install-peers at its default (off) in the CI .npmrc. If your team wants it for local ergonomics, scope it to developer machines, not the pipeline image.Auto-installation hurts both. Reproducibility: the resolved peer version depends on the state of the registry and the rest of the tree at install time, so two CI runs can produce different artifacts from the same commit. Security: an automatic resolver can pull in a newly published version you never vetted, expanding your supply-chain surface without a pull request ever showing the change. Explicit declaration plus a committed lockfile makes every dependency change a reviewed, auditable diff.
Put the rule where it is enforced, not just where it is read:
package.json explicitly and commit the updated lockfile. Do not enable auto-install-peers." .npmrc in the repo root so every environment inherits the same setting.Defaults vary by pnpm version, so confirm against the version in your CI image rather than assuming:
pnpm --version
pnpm config get auto-install-peers
pnpm install --frozen-lockfile # should fail on any missing peer
Then run one deliberate test: remove a peer from package.json on a branch and confirm the pipeline fails loudly instead of resolving it silently. If it passes, your enforcement is not working.
One caveat: if your monorepo mixes package managers (npm for one service, pnpm for another), peer resolution will differ between them. Standardize on one manager per repo before relying on any of the above.
Use comments to ask for clarification. Post a solution as an answer.
6,680 reputation · 24 Nov 2021, 13:09 UTC
.npmrc configuration. If your team finds manual declaration too cumbersome for large monorepos, you can use the auto-install-peers=true setting. However, to prevent the 'silent failure' mentioned earlier, this should be paired with a project-level .npmrc rather than a global environment variable.
Furthermore, pnpm offers a auto-install-peers-strict=false flag. This allows pnpm to install missing peer dependencies while still warning you about version mismatches. Using this in CI can be a middle ground: it allows the build to succeed while providing clear visibility in the logs that the dependency tree is suboptimal and requires future manual review.