Safeguard
Developer Tools•

npm-shrinkwrap.json vs package-lock.json: which one do you publish?

package-lock.json stays in your repo, while npm-shrinkwrap.json can ship in the package. See when each fits and why libraries should avoid shrinkwrap.

Safeguard Security Team
3 min read

package-lock.json is never published with your package, so it only controls installs inside your own project. npm-shrinkwrap.json has the same format but can be included when you publish, so it fixes dependency versions for people who install your package. Use it for deployed tools, not for libraries.

The one difference that matters

The npm documentation says npm-shrinkwrap.json is identical to package-lock.json with one major caveat: unlike package-lock.json, it may be included when publishing a package. If both files sit in a package root, npm prefers the shrinkwrap file.

Everything else, including the file format and what it records, is shared. Both pin exact resolved versions and integrity hashes.

Which projects should publish shrinkwrap

The docs say shrinkwrap is intended for applications deployed through the registry, such as daemons and command line tools installed globally or as devDependencies. In those cases the publisher wants every installer to get the same tested tree.

For libraries, the docs say it is strongly discouraged. Publishing a shrinkwrap would stop the people who use your library from controlling updates to transitive dependencies. If a vulnerable package sits in your pinned tree, every consumer inherits it until you publish again.

A decision table

Your package isPublish shrinkwrap?Why
A library imported by other projectsNoConsumers need control over transitive updates
A CLI installed globallyOften yesOne tested tree for every install
An internal service deployed from the registryOften yesReproducible deploys
An application in a repo, never publishedNoCommit package-lock.json instead

What to do in practice

  1. Always commit package-lock.json for projects you build.
  2. For a CLI or daemon you publish, generate the shrinkwrap with the npm shrinkwrap command and review it like any lockfile.
  3. Re-publish when a pinned dependency has a security fix, because installers cannot pick it up on their own.
  4. Check what goes into the tarball before you publish, as covered in npm pack dry run: check what you are about to publish.

Common mistakes

The first is publishing a shrinkwrap from a library because it feels safer. It freezes your consumers on your choices and leaves them waiting for you to release fixes. The second is assuming package-lock.json protects people who install your package. It does not leave your repository, so those users resolve the newest versions your ranges allow. The third is forgetting that shrinkwrap takes precedence over the lock file when both exist, so a stale shrinkwrap can silently override the lock file you update.

Quick check

Does npm publish package-lock.json?

No. The npm documentation notes that, unlike the lock file, only npm-shrinkwrap.json may be included when publishing.

Why is shrinkwrap discouraged for libraries?

It prevents consumers from controlling transitive dependency updates, so a vulnerable pinned version stays in their tree until you publish a new release.

Safeguard builds an SBOM from your lockfile and flags vulnerable components with reachability analysis. The free scan is at gold.safeguard.sh/scan.

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.