Commit your lockfile, install with npm ci, and keep a warmed cache or an internal mirror. The lockfile fixes exact versions, npm ci installs exactly those, and the cache can serve packages already downloaded. None of this helps for a package you never fetched.
What npm ci guarantees
The npm documentation says npm ci needs an existing package-lock.json or npm-shrinkwrap.json, exits with an error if the lockfile and package.json disagree instead of updating it, and leaves both files unchanged. It deletes any existing node_modules before installing and installs whole projects only.
That behavior is what you want in a recovery: the same versions every time, with no silent resolution to something new.
What the cache does
npm keeps a content-addressable cache of HTTP request data, in a folder named _cacache inside the cache directory. The documentation notes the default location is a folder named .npm in the home directory on POSIX systems. A command to verify the cache checks index and data integrity, and cleaning it needs the force flag.
A cache is only as complete as your past installs. A fresh CI runner has an empty cache, which is why many outages hit CI first.
Steps to prepare
- Commit the lockfile and require npm ci in CI. Fail the job if the lockfile is out of date.
- Persist the npm cache between CI runs, and treat it as untrusted storage that can be cleared.
- Stand up an internal registry mirror for the packages you depend on, so fresh machines have a source.
- On a test machine, disconnect the network, clear node_modules and run the install in npm's offline mode (check the current npm configuration docs for the exact setting). Record what fails.
- Add the missing packages to the cache or mirror and repeat until it passes.
What breaks anyway
- A package that was removed upstream and never cached.
- Packages whose install scripts download extra files from other hosts.
- A lockfile pointing at a registry address that is the one that is down.
- New dependencies, which need a source before they can be locked.
Security cautions
A cache or mirror that serves old versions will also serve old vulnerable ones. Keep scanning the lockfile, not just the registry. A warmed cache does not make a malicious version safe, so keep the review and release age checks you already use before adding new versions.
Try it yourself
Click through it at your own pace, or open it full screen.
Check how every package in a lockfile appears in the inventory, including indirect ones. Those are the packages your offline test must be able to find.
Safeguard scans lockfiles and produces an SBOM, and you can start with a free scan.
Quick check
Is npm install the same as npm ci in an emergency?
No. Install can change the lockfile and resolve new versions. Use npm ci so the result is repeatable.
Can I just copy node_modules between machines?
It can work for the same platform, but native modules are built per platform, so prefer a cache or mirror.
Sources
Last reviewed: 19 October 2026.