You need to ship @company/sdk and do not want to buy a box to run Verdaccio first. Start on cloud: create npm repos in the console, point the developer machine at one registry, and let CI publish with a Deploy Token (common prefix repod_). When partners refuse to hold a token, mark a delivery HOSTED public and let them copy credential-free install commands from /explore.
Takeaway: Cloud can host private npm; install via GROUP, publish to HOSTED; PROXY caches npmjs; public distribution uses a separate
public-*HOSTED plus host path/explore. Do not mark a GROUP public if it aggregates private members. Auth = repository ACL + tokens—there is no out-of-the-boxtenant_id.
If you need Community self-host and a full install.sh walkthrough, see the reference at the end: how to set up a private npm registry. For diagnosing flaky direct access to npmjs and verifying PROXY cache hits, see: when npmjs is flaky in China—this article only covers cloud getting started and public discovery, not the long troubleshooting piece.
1. Cloud vs Community self-host
| Path | Fit | Notes |
|---|---|---|
| Cloud | You do not want to own machines and certs | Managed HTTPS; sample host https://repo.anguskit.com. Trust the console connection config for your tenant host |
| Community self-host | Data must stay on your network | GPL-3.0; you own machines, certs, and networking |
Usage and limits follow what the console shows for the current tenant; publish / upload is rejected when you hit the ceiling.
2. Minimal topology (same three repos on cloud)
| Example name | Type | Role |
|---|---|---|
npm-hosted |
HOSTED | Only target for npm publish; disable overwrite of release versions |
npmjs-proxy |
PROXY | Remote https://registry.npmjs.org, read-only cache |
npm-all |
GROUP | Unified registry for developers / CI; member order hosted → proxy |
Rule of thumb: pull GROUP, push HOSTED, PROXY is read-only.
GROUP packuments are a union across members; on name conflicts HOSTED wins, which helps reduce dependency confusion. Developers remember one install URL.
CI (repod_) ──publish──► npm-hosted (HOSTED)
Dev machine ──registry──► npm-all (GROUP) ──► hosted + npmjs-proxy
Partner ──anonymous──► /explore ──► public-npm (public HOSTED, separate)
3. Hands-on steps
3.1 Console: repos and tokens
- Sign in to the cloud console and create the three npm repos above (names are yours—keep later config consistent).
- Create a Deploy Token for CI (common prefix
repod_) with Write onnpm-hosted; give developers Read onnpm-all. For personal debugging you can also use a user access token (PAT) issued from the portal. - The token is shown once: put it in a CI secret / local env var—never commit it to Git.
Fields and paths follow the console connection config; format detail is in the reference: npm format manual. Full self-host install is out of scope—see: how to set up a private npm registry.
3.2 Project .npmrc (HTTPS)
Migration-friendly: company scope only (public packages stay on the old source):
@mycompany:registry=https://repo.anguskit.com/npm/npm-all/
//repo.anguskit.com/npm/npm-all/:_authToken=${NPM_TOKEN}
//repo.anguskit.com/npm/npm-hosted/:_authToken=${NPM_TOKEN}
Whole project defaults to the private registry:
registry=https://repo.anguskit.com/npm/npm-all/
//repo.anguskit.com/npm/npm-all/:_authToken=${NPM_TOKEN}
//repo.anguskit.com/npm/npm-hosted/:_authToken=${NPM_TOKEN}
Three frequent traps:
-
The registry URL needs a trailing
/—missing it is the most common footgun. -
The
_authTokenline must not includehttps://; the host path must match the registry (including path and trailing slash). -
An old
package-lock.jsonlocks the public registry—after you switch, delete the lock and reinstall, or bulk-editresolved, or installs still hit npmjs.
npm CLI removed always-auth as of 7.10—writing it does nothing. Rely on URL-scoped _authToken for metadata and tarballs. pnpm ≥11.5.3 has extra limits on project-level ${...} credential lines—see: pnpm / yarn private registry.
3.3 Publish and install loop (acceptance)
export NPM_TOKEN="your_token" # inject via CI Secret
# Confirm the token works on HOSTED first
npm whoami --registry https://repo.anguskit.com/npm/npm-hosted/
# Publish to HOSTED (scoped packages default to private publish)
npm publish --registry https://repo.anguskit.com/npm/npm-hosted/ --access restricted
# Clean directory: install via GROUP
npm view @mycompany/hello --registry https://repo.anguskit.com/npm/npm-all/
npm install @mycompany/hello --registry https://repo.anguskit.com/npm/npm-all/
Acceptance: whoami OK → publish OK → another clean directory can view / install via GROUP. If whoami fails, do not publish yet. For 401 / scope mismatches see: npm publish 401 troubleshooting.
On the same machine, run a “fake clean” check so local cache does not fake a pass:
# Effective registry—confirm it is not still global npmjs
npm config get registry
# With a scope map, @mycompany should point at GROUP
npm config get @mycompany:registry
Whether public packages hit PROXY, and how to triage flaky direct access, is in: when npmjs is flaky in China—do not read that and this getting-started guide as two copies of the same tutorial.
4. Public discovery with /explore
When partners will not hold a token:
- Create a separate
public-npm(HOSTED) and mark it public (isPublic). Do not publicize day-to-daynpm-hosted, and do not publicize a GROUP that aggregates private repos. - Use a Write token (
repod_or PAT) to publish release versions only topublic-npm(no SNAPSHOT). - Open
https://repo.anguskit.com/explorein a private window (or search on/explore/artifacts), open the detail page, copy the credential-free install command, and run it in a clean environment.
Portal rules and acceptance checklist: how to publish private artifacts for public download. Portal and console share one instance; after you flip public, the index may lag by tens of seconds to a few minutes. While the portal top-bar “Docs” entry stays disabled, point outsiders at the AngusKit docs site—do not promise in-portal docs.
5. Boundaries and failure table
| Symptom | Likely cause | Fix |
|---|---|---|
| Storage full / publish rejected | Usage ceiling (current tenant in console) | Clean old packages or versions; or move to Community self-host |
| publish 401 | Token bound to wrong repo, missing /, mixed HTTP |
Match connection config and _authToken host path |
| install still hits npmjs |
registry not on GROUP, or lock locks old host |
npm config list; clear lock and reinstall |
| Partner 401 | Linked to a private repo | Use the anonymous command from the /explore detail page |
| Cannot create more repos | Repo count ceiling (console) | Merge HOSTED / PROXY / GROUP / public roles |
| Dependency confusion | Internal name equals a public package and GROUP order is wrong | HOSTED first; company scope for internals |
Admission gate is off by default; Repo does light enforcement, deep findings live in AngusSecurity—blocked uploads: artifact admission gate.
FAQ
Can cloud ship production packages?
Technically yes. Whether it is enough depends on the current tenant’s usage and limits in the console; high production traffic or compliance needs may push you to Community self-host.
How is this different from Verdaccio / self-host?
Cloud removes Compose and cert ops; the topology is still HOSTED / PROXY / GROUP. For air-gapped builds see: offline build warm-up.
Can /explore replace ACL?
No. Public only solves anonymous read distribution; per-person auth still uses repository ACL + tokens.
What happens when usage hits the ceiling?
Follow the usage and limits shown for the current tenant; publish / upload is rejected at the ceiling. Clean old packages or switch to Community self-host, then retry.
Takeaways
- Cloud can run the main private-npm path (three-repo topology).
- Developers use one GROUP; CI writes only HOSTED (
repod_). - External distribution:
public-npm+/explore, no SNAPSHOT.
Reference articles
- How to set up a private npm registry (self-host): https://www.anguskit.com/en/blog/npm-private-registry
- npm format manual: https://www.anguskit.com/en/docs/repo/manual/05-formats/03-npm
- Public portal manual: https://www.anguskit.com/en/docs/repo/manual/15-portal
- Publish private artifacts for public download: https://www.anguskit.com/en/blog/public-portal-launch
- Deploy Token and ACL: https://www.anguskit.com/en/blog/angusrepo-deploy-token-pat-acl-guide
- pnpm / yarn private registry: https://www.anguskit.com/en/blog/pnpm-yarn-private-registry
- npm publish 401 troubleshooting: https://www.anguskit.com/en/blog/npm-publish-401-troubleshooting
- Artifact admission gate: https://www.anguskit.com/en/blog/artifact-repo-vulnerability-license-scanning
- Offline build warm-up: https://www.anguskit.com/en/blog/offline-build-maven-npm-warm-cache
- When npmjs is flaky in China: https://www.anguskit.com/en/blog/npmjs-registry-alternative
Top comments (0)