Safeguard
Developer Tools•

npm ci vs pnpm frozen-lockfile vs yarn immutable: how do they compare?

Each package manager has a CI install mode that fails when the lockfile is out of sync. Compare npm ci, pnpm frozen lockfile and yarn immutable defaults.

Safeguard Security Team
4 min read

All three package managers have a strict install mode for CI: npm ci, pnpm install with the frozen lockfile option, and yarn install with the immutable option. Each refuses to change the lockfile and fails if it does not match package.json. They differ in defaults, so confirm what your CI actually runs.

The three modes side by side

npmpnpmYarn
Commandnpm cipnpm install with frozen lockfileyarn install with immutable
Fails if lockfile and manifest disagreeYesYesYes, if the lockfile would be modified
Needs a lockfileYesYes, in CIYes
Default in CIIt is the command itselfTrue in CI when a lockfile is presentTrue on CI
Also doesDeletes node_modules firstSkips staleness checks only with other optionsImmutable cache and check cache options exist

What the docs say

For npm, the documentation says npm ci is a clean install for automated environments. It requires an existing package-lock.json or npm-shrinkwrap.json, deletes any existing node_modules, never modifies package.json or lock files, and exits with an error if the lock file does not match package.json. It cannot add individual dependencies.

For pnpm, the install reference says frozen lockfile makes pnpm fail if the lockfile is out of sync with the manifest. It is true in CI when a lockfile is present, with CI detected from environment variables such as CI and BUILD_NUMBER.

For Yarn, the install reference says immutable aborts with an error if the lockfile would be modified, and defaults to true on CI. Separate options cover the cache folder, and check cache refetches every package and verifies checksums.

Why this matters for security

A lockfile only protects you if the build uses it. A plain install can quietly rewrite the lockfile, resolve a newer version, and ship something nobody reviewed. A strict mode turns that into a failed build, which is the safe failure.

Extra care for npm: if the lockfile was created with flags that change the tree, such as legacy peer dependencies, the docs say to pass the same flags to npm ci, ideally stored in a committed npmrc file.

Steps

  1. Pick the strict command for your package manager and put it in your CI config explicitly, even if it is the default.
  2. Fail the build on any lockfile change, and require lockfile updates to arrive in their own reviewed commit.
  3. Review the lockfile diff, looking at new packages and changed sources.
  4. Keep install steps separate from steps that run your own code, so a failed install stops early.

For the npm specifics see npm ci vs npm install for supply chain safety.

Try it yourself

Click through it at your own pace, or open it full screen.

Watch a pull request fail a policy check. A mismatched lockfile is the kind of thing a gate should catch.

Quick check

Does npm ci ever update the lockfile?

No. It never modifies package.json or lock files, and fails if they do not match.

Is the frozen lockfile option on by default in pnpm CI?

Yes, according to the pnpm docs it is true in CI when a lockfile is present.

Safeguard gates can review dependency changes in pull requests, and the free scan at gold.safeguard.sh/scan inventories what your lockfile resolves.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.