On a fresh clone, run npm ci. It installs exactly what package-lock.json describes and fails if package.json disagrees. Use npm install when you intend to add or change a dependency, because that command is allowed to rewrite the lockfile. Mixing them up is a common source of surprise diffs.
What each command does
The npm documentation for npm ci says it is meant for automated environments and any situation where you want a clean install. The differences it lists:
- A package-lock.json or npm-shrinkwrap.json must already exist.
- If the lock and package.json do not match, npm ci exits with an error instead of updating the lock.
- It installs whole projects only, so you cannot add one package with it.
- It removes an existing node_modules first.
- It never writes to package.json or any lockfile.
The lockfile page adds the reason this matters: the file describes the exact tree so teammates, deployments and continuous integration install the same dependencies.
A decision guide
| Situation | Command |
|---|---|
| First clone, nothing to change | npm ci |
| CI pipeline | npm ci |
| Adding a new package | npm install with the package name |
| Deliberate upgrade | npm install or npm update, then review the diff |
| Lockfile and manifest drifted | Fix the drift in a pull request, then npm ci |
Why this is a security matter
When an install silently updates the lockfile, you may pull versions nobody reviewed. A frozen install makes drift loud. If npm ci fails on your first day, that is useful information: someone changed package.json without regenerating the lock, or the lock was generated with different flags. The docs note that flags such as legacy peer deps or install links that shape the tree must be passed to npm ci as well, and suggest committing them in the project .npmrc.
Our guide on why npm ci fails when the lockfile drifts walks through fixes.
First-day routine
- Clone, then read package.json scripts and the .npmrc.
- Run npm ci.
- If it fails, do not delete the lockfile. Ask who owns the dependency files.
- When you need a new package, use npm install with its name, then inspect the diff in both package.json and the lockfile.
- Commit both files together.
Where Safeguard fits
Safeguard can do the inventory and watching for you. Its SBOM and dependency scanning lists what a repository actually pulls in, reachability analysis helps separate reachable findings from noise, and policies can gate a pull request. You can try a free scan on a repository to see the output.
Quick check
Is npm ci slower than npm install?
It deletes node_modules first, so speed varies. Speed is not the reason to choose it. Predictability is.
Can I use npm ci to add a package?
No. It installs whole projects only. Use npm install with the package name.
Sources
Last reviewed: 19 October 2026.