Safeguard
Developer Tools•

Does a scanner read your lockfile or what is actually installed?

Scanners may read the manifest, the lockfile or installed packages, and these can disagree. How to find out which yours reads and what that means.

Safeguard Security Team
3 min read

It depends on the tool, and the three sources can differ. A manifest holds ranges, a lockfile holds resolved versions, and the installed directory holds what actually landed. Find out which one your scanner reads, then make sure the other two stay in agreement with it.

Three records of the same thing

SourceWhat it holdsRisk if the scanner reads only this
ManifestVersion rangesCannot know the exact version
LockfileResolved versionsMay be stale versus the build
Installed packagesWhat truly existsOnly present after install

For npm, the documentation of npm ci describes the discipline that keeps these aligned. It requires an existing package-lock.json or npm-shrinkwrap.json, and if dependencies in the lock do not match package.json it exits with an error instead of updating the lock. It never writes to package.json or the lockfiles. That is why teams use it in CI: the install is frozen to the lockfile.

Where disagreement comes from

  • Someone ran an install that changed the tree and forgot to commit the lockfile.
  • Flags change the tree shape. The npm ci documentation notes that if you create the lockfile with flags that affect the dependency tree, such as legacy peer dependency handling, you must supply the same flags on install.
  • The build uses a different command than the lockfile was made for.
  • A base image or script adds packages outside the lockfile.

When these drift, a scanner reading the lockfile reports one world while production runs another.

Find out what yours reads

  1. Check the scanner documentation for which files it parses.
  2. Run a canary: put a vulnerable version in the lockfile only, scan, then put a different version in the installed directory only, scan again.
  3. Note which change the scanner reacts to.
  4. Document the answer in your coverage notes.

Keep the three in agreement

  1. Install in CI with the frozen command for your ecosystem, so the installed tree always equals the lockfile. See frozen installs in CI: the command for each language.
  2. Fail the build when the lockfile is out of date.
  3. Scan the built artifact or image as well, since that is the truth about what ships.
  4. Review lockfile diffs in pull requests.

Which should you prefer?

Scan the lockfile early for fast feedback, and scan the built output late for accuracy. Using both catches drift. A single point scan, whichever it is, leaves one blind side.

Safeguard offers SBOM and dependency scanning and a free scan at gold.safeguard.sh/scan. Confirm what any scanner reads with a canary.

Quick check

If my lockfile is committed, am I covered?

Only if the build installs exactly what it says. Frozen installs and a scan of the built output confirm that.

Why not scan only installed packages?

You can, but it requires an install and comes late. Lockfile scanning gives earlier feedback.

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.