Read the lockfile diff for added and removed packages, changed versions of packages you did not touch, and changed install scripts or sources. Then build in CI with npm ci, so the lock you reviewed is exactly the tree that ships.
What the lockfile is
The npm documentation says package-lock.json is generated automatically whenever npm modifies the node_modules tree or package.json, and it describes the exact tree that was generated, so later installs produce identical trees regardless of intermediate dependency updates. That makes it the record of what your web app actually contains.
When you upgrade a third party SDK, the lock is where the consequences appear. The package.json diff shows one line. The lock diff may show forty.
What to look for
- New packages. Each is new code in your bundle or your build. Ask what it is and who maintains it.
- Removed packages. Usually fine, and sometimes a sign the SDK slimmed down. Check that nothing you import directly vanished.
- Version changes on packages you never edited. The SDK's own dependency ranges moved them. Those are silent upgrades, as covered in our post on Gradle conflict resolution, which has the same shape in a different ecosystem.
- Changed resolved sources. A package that used to resolve from the registry and now points at a git address or a tarball URL deserves a question.
- Install scripts. Entries flagged as having install scripts run code on every machine that installs them. A new one is a reason to pause.
- Duplicates. Two copies of one library at different versions can grow your bundle and cause subtle behaviour differences.
A short procedure
- Check out the pull request and run an install from the lock to confirm it is consistent.
- Produce a summary of changes between the base and head lock, listing added, removed and changed packages. Most tools can do this, and a short script over the JSON can too.
- Sort by risk: new packages and install scripts first, version bumps second.
- For each new package, check the registry page, the repository, the maintainers and the publish date.
- Run your test suite and a production build, then compare bundle size.
Why npm ci matters
The npm documentation describes npm ci as similar to npm install but meant for automated environments such as test platforms and continuous integration. It requires an existing lockfile. If dependencies in the lock do not match package.json, npm ci exits with an error instead of updating the lock.
That behaviour is the control. With npm install in CI, a mismatch can quietly rewrite the lock and ship something nobody reviewed. With npm ci, the build fails and someone has to look.
| Command | Updates lock on mismatch | Suited to |
|---|---|---|
| npm install | Yes | Local upgrade work |
| npm ci | No, it errors | CI and release builds |
Try it yourself
Click through it at your own pace, or open it full screen.
Note how many components sit below the one you chose to add.
Where Safeguard fits
Safeguard's dependency scanning and SBOM output provide a package level inventory you can compare between builds, and its policies can flag packages that were not there before. A free scan is at gold.safeguard.sh/scan.
Quick check
Does npm ci ever change the lockfile?
No. According to the npm documentation it errors when the lock and package.json disagree instead of updating the lock.
Should I review the lock diff or the package.json diff?
Both, but the lock diff shows the real change. The package.json diff is usually one line.
Sources
- npm Docs, package-lock.json: https://docs.npmjs.com/cli/v10/configuring-npm/package-lock-json
- npm Docs, npm ci: https://docs.npmjs.com/cli/v10/commands/npm-ci
Last reviewed: 19 October 2026.