Documentation is currently available in English only. We're working on translations.

Home / Docs / npm Guide / Setup

Private npm Registry

Publish private packages, install them anywhere, and optionally route all of npm through NugetHosting.

5 min read

Prerequisites

  • Node.js and npm 7 or newer
  • An access token from the Tokens page

Note: The npm registry requires a Starter plan or higher. Upgrade your plan if needed.

Configure .npmrc

Point your scope at NugetHosting and add your token. Put this in the .npmrc at the root of your project:

Use your own scope: Every organization gets its own npm scope. Replace @your-org below with yours — you can see it and rename it on the npm page of your dashboard, which also shows these commands already filled in.

@your-org:registry=https://npm.nugethosting.com/
//npm.nugethosting.com/:_authToken=${NPM_TOKEN}

Keep tokens out of git: Reference an environment variable as shown above rather than pasting the token. npm expands ${NPM_TOKEN} at runtime.

Publishing

Make sure your package.json name uses your scope, then publish as usual:

# package.json → "name": "@your-org/my-package"
npm publish

Republishing a version that already exists is rejected with a 409, the same as the public registry. Bump the version first.

Installing

npm install @your-org/my-package

Tarballs are served with an immutable cache header and verified through dist.integrity, so lockfiles stay reproducible.

Proxy Mode

NugetHosting can also stand in front of the public registry. Point your whole registry at it and any package that is not yours is fetched from registry.npmjs.org and cached:

registry=https://npm.nugethosting.com/
//npm.nugethosting.com/:_authToken=${NPM_TOKEN}

Running this way buys you three things:

  • One registry for private and public packages, so a single line of config per project.
  • Installs keep working from the cached copy when registry.npmjs.org has an outage.
  • A package you publish privately shadows the public one of the same name, which makes internal forks transparent.

Storage: Cached public packages are shared across the platform and do not count against your storage quota or package limit.

Dist-tags

Dist-tags work as they do on the public registry. The first version you publish becomes latest automatically.

npm dist-tag add @your-org/[email protected] beta
npm dist-tag ls @your-org/my-package

CI/CD

Write the .npmrc from a secret at build time:

- name: Configure npm
  run: |
    echo "@your-org:registry=https://npm.nugethosting.com/" >> .npmrc
    echo "//npm.nugethosting.com/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc

- name: Publish
  run: npm publish

Restrict the token: Tokens support an IP whitelist. If your runners have static egress IPs, add them when you create the token.

Troubleshooting

401 Unauthorized on install or publish

The _authToken line must match the registry host exactly, without a protocol and with a trailing slash before the colon. Run npm config list to see what npm actually loaded.

Package installs from npmjs.org instead

The scope line is missing or misspelled. A scoped registry only applies to that exact scope, so @your-org in .npmrc must match the name in package.json.

403 with an upgrade message

Your plan does not include the npm registry, or you reached the package or storage limit. Check Usage & Limits.

409 Conflict when publishing

That version already exists. Versions are immutable, so bump the version in package.json.

Was this page helpful?