When npm install appears frozen, repeatedly restarting it usually hides the useful evidence. The delay is commonly caused by network access, proxy configuration, dependency resolution, a lifecycle script, native compilation, cache damage, or a Node.js version mismatch.
1. Capture detailed logs
Run the install with verbose output:
1 | npm install --verbose |
Also record the active toolchain and configuration:
1 | node --version |
A line such as idealTree:userRequests describes the dependency-resolution stage; it is not the root cause by itself. Inspect the requests and messages immediately before and after it.
2. Test registry and DNS access
Verify that npm can reach the registry:
1 | npm ping |
If these commands are slow, check DNS, VPN, firewall, corporate TLS inspection, and proxy settings. Review both npm-specific and environment proxies:
1 | npm config get proxy |
Remove stale npm proxy values when they are no longer required:
1 | npm config delete proxy |
Do not disable TLS verification as a permanent workaround. Install the correct organization CA certificate instead.
3. Verify the cache
Use npm’s built-in verification first:
1 | npm cache verify |
Cache deletion should be a targeted experiment, not the default first step. If verification reports corruption and you have ruled out network problems, use:
1 | npm cache clean --force |
4. Separate dependency resolution from scripts
Packages may run preinstall, install, or postinstall scripts that download binaries or compile native modules. Test without scripts:
1 | npm install --ignore-scripts |
If that completes, inspect lifecycle scripts and rerun the relevant one with foreground output:
1 | npm install --foreground-scripts --verbose |
Native builds may require Python, a C/C++ toolchain, and platform development headers.
5. Check the lockfile and Node version
For CI and reproducible installs, prefer:
1 | npm ci |
It requires package.json and package-lock.json to agree. Do not delete a committed lockfile casually; doing so changes the resolved dependency graph. Confirm the project’s supported Node version through .nvmrc, .node-version, the engines field, or project documentation.
6. Find the slow package
Useful experiments include:
1 | npm install --timing |
Check the npm debug log path printed by the failed command. Git-based dependencies may be waiting on SSH credentials, inaccessible hosts, or Git LFS. Browser automation packages often download large binaries and can be blocked by proxies.
A reliable cleanup sequence
After preserving the original error, a controlled local retry is:
1 | rm -rf node_modules |
Keep the lockfile unless you intentionally want to update dependencies. In CI, add explicit timeouts and cache keys based on the lockfile so a stalled registry request cannot block a runner indefinitely.
