npm install hangs on registry.npmjs.org with timeouts, ECONNRESET, occasional TLS handshake failures, or upstream 502. I have seen the same office network where a phone hotspot works and company DNS fails every time—and CI images where NPM_CONFIG_REGISTRY still points at the official host after the laptop already switched. Bookmarking another public mirror URL often treats the symptom: private packages still need a second address, and CI drifts from local. A stabler path: developers / CI only know the team GROUP, public packages cache through PROXY, internals stay on HOSTED. This article assumes the three repos and tokens are already set up per “Start a free cloud npm private registry” or “How to set up a private npm registry,” and focuses on reachability diagnosis and cache-hit acceptance.
Takeaway: Use a private registry GROUP as the only install source and PROXY to cache npmjs—you can replace direct hits to the official registry from developers/CI. PROXY still needs outbound access to npmjs on a cold miss; after a local hit, build machines stop each slamming upstream jitter. This does not replace npmjs’s global package identity or account system.
Repo creation, .npmrc getting started, and the npm publish loop: Start a free cloud npm private registry / How to set up a private npm registry. Below starts from the “flaky” symptoms.
1. Recognize what “flaky” looks like
| Client symptom | More likely layer | Do this before swapping registries |
|---|---|---|
ENOTFOUND / slow resolve |
DNS / office hijack |
nslookup registry.npmjs.org; compare phone hotspot |
ECONNRESET, TLS alert, handshake drop |
TLS / MITM proxy / cert chain | Check corporate HTTPS proxy; do not paper over production CI with self-signed certs |
| Long hang then timeout | Congestion or slow upstream | Note failure time; retry the same command via GROUP |
401 / E401
|
Token or registry path—not “China network” | Check _authToken host path and trailing / (failure table) |
Occasional 502 / 503 from npmjs |
Upstream or a gateway on the path | Should be rarer after PROXY hits; cold misses can still reproduce |
“npmjs alternative” here means unified registry + cache + private packages on one host—not a claim to replace the whole ecosystem.
1.1 Public mirrors vs private registry (scope)
| Need | Public mirror (e.g. regional) | Private GROUP + PROXY |
|---|---|---|
| Only make public packages faster / more reachable | Usually enough | Works, but heavier |
Private scope and public packages on one registry
|
Usually no | HOSTED + PROXY in one GROUP |
| Per-repo ACL / Deploy Token / audit | No | Yes |
| Fully air-gapped builds | No | Warm cache first—see offline builds |
2. Traffic boundary (read GROUP, write HOSTED)
Dev / CI
registry = …/npm/npm-all/ (GROUP, only install entry)
├─ npm-hosted (HOSTED, internals first)
└─ npmjs-proxy (PROXY → https://registry.npmjs.org)
- Read: only configure GROUP (member order hosted → proxy).
-
Write: only
npm publishto HOSTED (steps in the free-cloud npm article—not repeated here). -
Auth:
.npmrcuses URL-scoped_authToken=${NPM_TOKEN}; never commit the token. No out-of-the-boxtenant_id. -
Outbound: the repository node must still reach
https://registry.npmjs.org—on a cold miss the unified registry concentrates upstream jitter on the repo side.
Cloud sample host: repo.anguskit.com; self-host swaps your domain.
3. Diagnosis: flaky direct → confirm switch → accept PROXY
3.1 Confirm where traffic actually goes
On the same failing machine / same CI job:
# Effective registry (including project overrides)
npm config list -l | rg -i 'registry'
# Env vars CI images often inject quietly
env | rg -i 'npm_config_registry|NPM_CONFIG_REGISTRY'
# Lock files still pinning the official host?
rg -n 'registry\.npmjs\.org' package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null | head
If registry is still https://registry.npmjs.org/, or locks are full of resolved pointing at npmjs, every later “switch” check is invalid—fix config or clear the lock and reinstall first (detail: free-cloud npm article §3.2 three traps).
3.2 Compare: direct fail vs via GROUP
Do not invent speed numbers. Same command, same dependency, two adjacent runs—watch whether the failure shape changes:
# A. Direct official (reproduce flaky)
npm install lodash --registry https://registry.npmjs.org/ --prefer-online
# B. Via team GROUP (should hit PROXY; first run may miss)
npm install lodash --registry https://repo.anguskit.com/npm/npm-all/ --prefer-online
Reading:
| A (direct) | B (GROUP) | Meaning |
|---|---|---|
| Timeout / TLS / 502 | Success or clearly stabler | Unified path helps; continue §3.3 cache acceptance |
| Success | 401 | Path works; token / _authToken path is wrong |
| Timeout | Same timeout | Check repo outbound to npmjs; or the machine cannot reach the repo host |
| 401 | 401 | Stop talking about network; fix auth first |
3.3 Confirm PROXY cache, not every request going upstream
Goal: the second install does not spend a long time missing; the console shows PROXY-side cache entries (field names follow the console).
- Open
npmjs-proxy(or your PROXY name) → check whether the package you just installed (e.g.lodash) appears in cache / artifact lists. - Install again in the same clean directory (delete
node_modules, keep a lock already pointed at GROUP):
rm -rf node_modules
npm install lodash --registry https://repo.anguskit.com/npm/npm-all/
- Observe: the second run should be clearly faster or stop hanging on “resolving / downloading registry.npmjs.org”; if it still spends a long time missing, check PROXY remote URL is
https://registry.npmjs.org, repo outbound, and whether--prefer-online/ cache policy forces a refresh (console + manuals). - On failure, prioritize repo outbound and PROXY config—not a third mirror URL on every laptop.
Warming core deps and weak/offline builds: offline build warm-up.
3.4 Boundaries where the unified registry can still “feel like official”
| Case | Notes |
|---|---|
| PROXY cold miss | Still depends on npmjs and repo outbound; unified registry concentrates jitter, it does not erase upstream |
Global ~/.npmrc overrides the project |
One laptop still goes direct; use §3.1 on the offending machine |
| CI base image hard-codes registry |
npm config get registry in the job log shows it immediately |
| Only company scope switched; public packages still direct | Fine during migration; when public packages are flaky, set whole-project registry= to GROUP |
4. Boundaries and failure table
| Symptom | Cause | Fix |
|---|---|---|
| Still hits npmjs | Global .npmrc / env / lock override |
§3.1 three commands; clear lock and reinstall |
| GROUP install 401 |
_authToken host path mismatch or missing trailing /
|
Scoped line has no https://; align with registry URL |
| Private package 404 | Published to wrong repo or GROUP missing HOSTED | Check member order; publish steps in free-cloud npm article |
| Assumed “alternative” means no npmjs | Cold PROXY still misses | Allow repo outbound; warm hot packages |
| Dependency confusion | Internal name equals public and order is wrong | HOSTED first; company scope for internals |
For partners installing anonymously, use /explore and a public HOSTED—see public portal.
FAQ
Does this replace npmjs.org?
For the team default install source and private package hosting, yes. Publishing to public npmjs and the official account/org system stay on npmjs. “Alternative” here is unified registry / cache—not replacing the ecosystem.
How to choose vs Taobao-style public mirrors?
See §1.1: public mirrors buy reachability; private registry buys private packages + cache + ACL + audit on one host. They can coexist; migration can start with company scope only.
How does this map to Nexus / Verdaccio?
Multi-format and alternative scenarios: selection article; leaving Verdaccio: Verdaccio migration.
Takeaways
- Separate DNS / TLS / timeout / 401 before talking about switching registries.
- Use §3.1–3.3 to accept “already on GROUP” and “PROXY cache hit.”
- A unified registry does not cancel upstream: cold misses can still feel npmjs.
Reference articles
- npm format manual: https://www.anguskit.com/en/docs/repo/manual/05-formats/03-npm
- How to set up a private npm registry: https://www.anguskit.com/en/blog/npm-private-registry
- Start a free cloud npm private registry: https://www.anguskit.com/en/blog/free-npm-registry-cloud
- Offline / intranet builds: https://www.anguskit.com/en/blog/offline-build-maven-npm-warm-cache
- pnpm / yarn private registry: https://www.anguskit.com/en/blog/pnpm-yarn-private-registry
- Migrate from Verdaccio to AngusRepo: https://www.anguskit.com/en/blog/migrate-from-verdaccio-npm-registry
- Selection: one registry instead of many: https://www.anguskit.com/en/blog/repo-selection-2026
- Public portal /explore: https://www.anguskit.com/en/blog/public-portal-launch
Top comments (0)