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
2
3
4
node --version
npm --version
npm config get registry
npm config list

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
2
3
npm ping
npm view lodash version
curl -I https://registry.npmjs.org/

If these commands are slow, check DNS, VPN, firewall, corporate TLS inspection, and proxy settings. Review both npm-specific and environment proxies:

1
2
3
npm config get proxy
npm config get https-proxy
env | grep -i proxy

Remove stale npm proxy values when they are no longer required:

1
2
npm config delete proxy
npm config delete https-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
2
3
npm install --timing
npm explain package-name
npm ls

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
2
3
rm -rf node_modules
npm cache verify
npm ci --verbose

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.