npm ci is the npm command for installing a project’s dependencies from a lockfile in a clean, repeatable way. It removes existing modules first, then installs exactly the locked versions, making it suitable for automated builds and reducing drift between environments.
What npm ci does, and why it matters in builds
npm ci is designed for clean, repeatable dependency installation from a lockfile. That makes it especially useful when you need the same dependency graph across developer laptops, ci runner, and release pipelines without carrying forward stale local state.
The key operational value is determinism. By clearing out existing modules first and reinstalling exactly what the lockfile specifies, it reduces the risk that one environment silently drifts from another because of a previous install, a changed transitive dependency, or leftover files in node_modules.
That repeatability is more than convenience. In software delivery, dependency drift can turn into inconsistent test results, unreviewed package changes, or a build that passes locally but behaves differently in production. A clean install step is one of the simplest ways to make the build output easier to trust.
How npm ci differs from a normal install
Compared with a standard npm install, npm ci is stricter and more automation-friendly. It is intended for environments where the lockfile is the source of truth and where consistency matters more than interactive flexibility.
In practice, that means it fits continuous integration, container image builds, and other repeatable pipelines better than ad hoc developer workflows. The command is not trying to resolve or negotiate package versions on the fly, it is trying to reproduce an already-declared set of dependencies as faithfully as possible.
This distinction is important because many supply-chain failures begin with ambiguity in how dependencies are resolved. If a build process is supposed to be deterministic, a command that honours the lockfile exactly is easier to reason about than one that may update the dependency tree as part of the install step.
Lockfile fidelity and dependency hygiene
npm ci only delivers value when the lockfile is treated as a controlled artifact. If the lockfile is outdated, tampered with, or committed without review, the install remains repeatable, but it faithfully repeats the wrong thing.
For that reason, teams usually pair npm ci with disciplined dependency review, source control hygiene, and package provenance checks. The goal is not just a fast install, but a reproducible one that matches what was actually approved for the build.
It is also a good fit for environments that want to reduce “works on my machine” behaviour. When local residue is removed before installation, the command helps surface whether a project truly builds from declared inputs rather than from incidental state left behind by earlier runs.
For a broader discussion of lockfiles, install scripts, trusted publishing, and build integrity, see Node.js Security Guide and OWASP CI/CD Top 10 CICD-SEC-3 Dependency Chain Abuse Guide.
Where npm ci fits in secure delivery pipelines
In secure build pipelines, npm ci is usually one control in a larger chain of dependency and supply-chain protections. It helps make the install step deterministic, but it does not by itself validate package intent, suppress malicious lifecycle scripts, or stop compromised upstream packages from being installed if they are already locked in.
That means it should be viewed as a reliability and reproducibility control, not a complete supply-chain defence. The strongest use case is when teams combine it with review of the lockfile, restricted install behaviour, trusted package sources, and post-install security checks.
Used well, npm ci narrows the room for accidental drift and makes build behaviour easier to reproduce during incident response or forensic review. Used alone, it can still faithfully reproduce a dependency set that is technically consistent but operationally unsafe.
When the subject is secure JavaScript delivery, repeatability is only one part of the answer, so the pipeline should also reflect guidance from NIST Cybersecurity Framework 2.0 and the npm-specific control ideas in Node.js Security Guide.
Risk and Threat Considerations
npm ci lowers build drift, but it can also make unsafe dependency state repeatable at speed. If a malicious package, compromised maintainer account, or poisoned lockfile reaches the pipeline, a clean install step can rapidly reproduce that dependency set across every build.
Failure mechanism: Attackers target the dependency chain, package maintainer accounts, or lockfile integrity so that automated installs pull in malicious code or reintroduce compromised packages during every clean build.
Impact: The result can be credential theft, backdoored builds, poisoned artifacts, or repeated execution of malicious install logic across CI and release systems.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
SLSA, CIS Controls v8, OWASP SAMM and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| SLSA | Supply-chain Levels for Software Artifacts | npm ci supports reproducible artifact builds from locked inputs. |
| Recommendation — Use reproducible builds and verified provenance to keep dependency resolution deterministic. | ||
| CIS Controls v8 | CIS-16 — Application Software Security | The term is about secure dependency handling in software delivery. |
| Recommendation — Apply secure SDLC controls to review and govern third-party dependencies before release. | ||
| OWASP SAMM | Software Assurance Maturity Model | npm ci fits software delivery practices that seek repeatable, controlled builds. |
| Recommendation — Build dependency governance into the software delivery lifecycle and enforce repeatable builds. | ||
| NIST CSF 2.0 | PR.DS-10 — Integrity is protected | The command reduces unintended dependency drift and helps preserve build integrity. |
| Recommendation — Protect build integrity by ensuring the installed dependency set matches the approved lockfile. | ||
Practitioner Guidance
Why practitioners should care: npm ci is best used when you want reproducibility to be a guarantee, not a hope. It is a strong default for CI and release builds, but only when the lockfile is reviewed, committed intentionally, and treated as part of the software supply chain.
Common misunderstanding: teams sometimes assume that “clean install” also means “safe install”. It does not. npm ci removes environmental noise, but it still installs whatever the lockfile and registry supply at that moment.
Practitioner takeaway: Use npm ci to stabilise build behaviour, then pair it with provenance, dependency review, and source controls that reduce the chance of reproducing a compromised package set.
Related resources from NHI Mgmt Group
- Who should be accountable when compromised npm packages spread through CI and developer systems?
- What breaks when malicious npm packages execute during CI/CD installs?
- How should security teams handle reusable secrets in npm build and CI environments?
- What should teams do after a malicious npm package has run in CI/CD?