Skip to content

Create a private npm registry

Reserve a scope on the shared registry or create a private registry on your domain. Then create a publisher key and a download key, and publish the first version.

Overview

This guide tells you how to create a place to publish private npm packages on PrivateNPM.com. You reserve a scope on the shared registry, or you create a private registry on your own domain. Then you create a publisher key, publish the first version and create a download key for the first recipient.

At the end of the guide, a release job can publish @acme/sdk, and a recipient can install it with a read-only key. The guide is for the organization admin who configures the registry for a team or for external recipients.

Before you start

Make sure that these conditions are true before you start:

  • You have a PrivateNPM.com organization. If you do not have one, create an organization. A new organization starts with a trial.
  • You have the admin role in the organization. The admin role can create registries, reserve scopes, verify domains and create keys.
  • You have Node.js and a current npm CLI on the machine that publishes. The examples use npm 10 or 11.
  • For a private registry, you can create DNS records for a hostname that you own, such as npm.acme.com.

Decide on these values before step 1:

  • The scope name, for example @acme. Scope names use lowercase letters, digits, and the characters ., _, ~ and -.
  • The registry type: the shared registry or a private registry.
  • For a private registry, the hostname and the package storage region.
  • The name of the environment variable that holds the key. The examples use ACME_NPM_TOKEN.

During a trial without a payment method, your organization can publish up to 3 packages with 10 GB of stored content. To publish more, an organization admin must add a payment method under Organization → Plan & usage.

How it works

A registry is a package namespace in one format. Package names are unique in each registry, not across all registries. Thus @acme/sdk in your private registry and @acme/sdk in the shared registry are two different packages.

The shared registry and its scopes

The shared registry is one npm host, registry.privatenpm.com, that all organizations use. Each organization can reserve one scope on the shared registry. The scope is your claim on part of the shared namespace. Every package that you publish on the shared registry must use that scope.

The database enforces the rule of one scope for each organization. When an organization reserves a scope, no other organization can reserve the same scope. The shared registry is ready at once, because it needs no DNS configuration. Its package files always use global storage.

Private registries and custom domains

A private registry is a namespace that your organization owns. It serves npm on a custom domain that you verify, such as npm.acme.com. In a private registry, you can publish unscoped names such as sdk. You can also reserve as many scopes as you need in that registry.

A private registry serves no requests until its hostname is active. To activate the hostname, you add a TXT record that proves ownership and a CNAME record that sends traffic to edge.privatenpm.com. The edge then gets a TLS certificate for the hostname. The domain verification guide explains each check.

Package storage region

When you create a private registry, the form can show Package storage region. The choices are Global (replicated worldwide), European Union (EU) and United States (US). The region applies to the package files of that registry. You cannot change the region later. To use a different region, create a new registry.

NOTE: The storage region applies to package files only. Accounts, package names, manifests, permissions and audit records stay on the shared platform.

Keys belong to one registry

Each publisher key and each download key works with one registry only. A key from the shared registry does not work on npm.acme.com, and a key from a private registry does not work on the shared host. The registry refuses a key from a different registry with the reason registry_not_in_token_audience.

Plan limits

The plan of your organization limits the number of private registries, packages and active download keys. The shared registry scope does not count as a private registry.

PlanPrivate registriesPackagesDownload keys
Starter1350
Growth3100500
ScaleNo limitNo limitNo limit
PlatformNo limitNo limitNo limit

The plans page shows storage, bandwidth and the other limits of each plan.

Reserve a scope on the shared registry

If names such as @acme/sdk on registry.privatenpm.com are sufficient for your packages, use this procedure.

  1. Open Registry → Registries. The page shows the Shared registry card and your private registries.
  2. On the Shared registry card, type acme or @acme in Scope name.
  3. Click Reserve scope. The card shows @acme as your reserved scope.

If a different organization holds the scope, the page shows "That scope is not available: it is already reserved." Select a different scope name. If your organization already holds a shared scope, the page tells you that each publisher holds at most one.

Create a private registry

If you need unscoped names, more than one scope, or an address on your own domain, use this procedure. Your plan must have a free private registry slot.

  1. Open Registry → Registries.
  2. Click New private registry.
  3. In Display name, type a name for your team, for example Acme packages.
  4. If the form shows Format, select npm.
  5. If the form shows Package storage region, select the region for the package files.
  6. In Registry hostname, type the hostname, for example npm.acme.com.
  7. Click Create and verify domain. The page shows a TXT record and a CNAME record.
  8. At your DNS provider, create the two records that the page shows.
  9. Wait until the registry card shows Ready. Until then, the card shows Needs DNS verification.
New private registry form with display name and registry hostname fields
Type a display name and the hostname that recipients will use.

The two DNS records for npm.acme.com have this form. Copy the exact TXT value from the page.

_privatenpm-challenge.npm.acme.com.  TXT    "<value from the page>"
npm.acme.com.                          CNAME  edge.privatenpm.com.

The registry checks the records automatically, first at short intervals and then less often. To start the checks at once, open the domain and click Check now.

To publish scoped names in the private registry, reserve the scope in that registry:

  1. On the registry card, click Manage registry.
  2. Under Package names and scopes, type the scope in Scope name.
  3. Click Reserve scope. The scope appears in the list.

Create a publisher key

A publisher key (prt_…) lets a developer machine or a CI release job publish to one registry. The key acts with the permissions of the member who creates it. Create one key for each machine or job.

  1. On the registry card, click Manage keys. The keys page of the registry opens.
  2. Click New publisher key.
  3. In Name, type the machine or job, for example sdk release CI.
  4. Under Publisher permissions, select Read metadata, Read tarballs, Publish and Write dist-tags.
  5. If the form shows Unpublish or Read public packages, clear them. Select them only if the job needs them.
  6. Under Package access, clear All packages. Then select your scope in Restrict to a scope.
  7. Optional: in Expires, set a date. The key stops at the start of that day.
  8. Click Create publisher key. The page Publisher key issued shows the secret.
  9. Copy the secret into your CI secret store or your password manager.

CAUTION: Copy the secret before you leave the page. The page shows a publisher key secret only once. If you lose the secret, rotate the key.

For the first publish of a new package, restrict the key to a scope, not to a package. A package that does not exist yet cannot be selected in Restrict to a package. After the first version exists, you can issue a key for that one package.

You can also run npm login --registry=https://registry.privatenpm.com/ on a developer machine. npm prints the address of an approval page. Open the address in a browser. Approve the request on that page. npm then writes a publisher key for that registry into ~/.npmrc. That key has all the permissions of your membership and no expiry date.

Publish the first version

Before you start, make sure that the registry is ready and that the publisher key secret is in the ACME_NPM_TOKEN variable.

  1. In package.json, set name to @acme/sdk and version to 1.0.0.
  2. Add publishConfig.registry to package.json. This entry sends npm publish to your registry and not to npmjs.org.
  3. Create .npmrc next to package.json with the scope line and the credential line.
  4. Run npm publish --dry-run. npm lists the files in the tarball and sends nothing.
  5. Run npm publish. npm prints + @acme/[email protected].
  6. Open Registry → Packages. The list shows @acme/sdk with version 1.0.0.
// package.json (part)
{
  "name": "@acme/sdk",
  "version": "1.0.0",
  "publishConfig": { "registry": "https://registry.privatenpm.com/" }
}
# .npmrc
@acme:registry=https://registry.privatenpm.com/
//registry.privatenpm.com/:_authToken=${ACME_NPM_TOKEN}

For a private registry, use the host npm.acme.com in all three places. The host in the credential line must be the same as the host in the scope line. The publish guide gives more examples, and trusted publishing removes the stored key from CI.

Create a download key

A download key (pdk_…) is a read-only credential for a recipient. A download key cannot publish. Create one download key for each recipient, team or CI build.

  1. On the registry card, click Manage keys.
  2. Click New download key.
  3. Under Who does this key belong to?, select A new recipient.
  4. In Recipient name, type the person, team or company.
  5. In Key name, type where the key is used, for example production CI.
  6. Under Access rule, select All packages in this registry, One npm scope or Selected packages.
  7. Click Create download key. The page Copy your download key shows the secret.
  8. Send the secret and the .npmrc lines to the recipient through a secure channel.
Selected packages access rule on the download key form
Select only the packages that the recipient must install.

All packages in this registry and One npm scope also include packages that you publish later. Selected packages includes only the packages that you select. If you publish a new package later, edit the key to add that package. An admin can show the secret of a download key again with Reveal key on the key details.

Verify the result

Do this test in a clean environment, such as a new container, so that no old credential or cache changes the result.

  1. Start a container: docker run --rm -it node:24 bash.
  2. Create an empty directory.
  3. In that directory, run npm init -y.
  4. Add the scope line and the credential line to .npmrc.
  5. Run export ACME_NPM_TOKEN=pdk_... with the download key.
  6. Run npm whoami --registry=https://registry.privatenpm.com/. npm prints download:rdk_….
  7. Run npm install @acme/sdk. npm installs the package with no error.
  8. Open the download key in the dashboard. Recent downloads shows the tarball download after a short delay.

With the publisher key, npm whoami prints the email address of the member who owns the key.

Troubleshoot

SymptomCauseCorrection
"the shared registry requires a scoped package name"The package name has no scope.Rename the package to @acme/<name>, or publish to a private registry.
"this scope is not reserved by your organization"The scope in the name is not your reserved scope.Reserve the scope, or correct the name in package.json.
"this publisher key cannot publish this package"The key has a different registry, scope or package, or no Publish action.Examine the key under Registry → Registry keys. Issue a key with the correct access.
"the organization's plan does not allow more packages"The organization reached the package limit of its plan or trial.Add a payment method or change the plan under Organization → Plan & usage.
"You cannot publish over the previously published versions"The version exists, or it was unpublished before.Increase the version and publish again.
ENOTFOUND or a certificate error on npm.acme.comThe hostname is not active yet.Open the domain under Registry → Domains. Correct the step that failed.
E401 on installnpm sent no key, or the key is revoked or expired.Make the two hosts in .npmrc the same. Make sure that the variable is set.

If the Registries page shows "Your plan has no remaining private registry slots", change the plan or delete an empty private registry. For other authentication failures, use the npm E401 guide.

Security and maintenance

WARNING: Do not commit a publisher key or a download key to source control. Anyone who can read the project can then publish or install your packages.

  • Keep one key for each machine, job or recipient. You can then revoke one holder and keep the others.
  • To replace a secret, click Rotate key on the key details. Rotation issues a new secret and keeps the access of the key.
  • To remove access, click Revoke key. A revoked key cannot be restored.
  • Set an expiry date on keys for contractors, trials and short projects.
  • Examine key, scope and registry changes under Organization → Audit log. Examine downloads under Registry → Activity.

CAUTION: Plan the hostname before you give it to recipients. A new hostname needs a new verification, and old .npmrc files and lockfiles continue to point to the old address.

A registry that holds or once held packages cannot be deleted. A scope that holds or once held packages cannot be deleted either. These rules prevent the return of a package name with different content.

Next: Publish a package

Build a typed package and publish its first version.

Publish a package

You need an organization to do these steps. Start a 30-day trial. Before you add a card, you can publish 3 packages and store 10 GB of content.

READY WHEN YOU ARE

Put private packages to work.