Skip to content

Publish your first private package

Reserve a scope, publish a small JavaScript package and install the package in another project. No custom domain or build tools required.

Publish a small JavaScript package. Then install the package in a separate project with a read-only download key.

The shared registry needs no custom domain or DNS configuration. A scope is the prefix in a package name, such as @acme.

Before you start

  • Create an organization and confirm your email address, or sign in.
  • Use the Admin role to reserve a scope and create keys.
  • Install Node.js 24 and npm 11. The example needs no build tools or dependencies.

The 30-day trial needs no card. Before you add a card, you can publish up to 3 packages with 10 GB of stored content.

The commands use @acme. Replace acme with your reserved scope in each file and command.

1. Reserve your scope

  1. Open Registry → Registries.
  2. On the Shared registry card, enter an available Scope name.
  3. Click Reserve scope. The card shows your scope.

If your organization already has a shared scope, use that scope. Each organization can reserve one shared scope.

2. Create a publisher key

  1. On the shared registry card, click Manage keys.
  2. Click New publisher key.
  3. Enter a name such as First package.
  4. Under Publisher permissions, select Publish and Read metadata.
  5. Clear the other actions.
  6. Under Package access, clear All packages.
  7. Restrict the key to your reserved scope.
  8. Click Create publisher key.
  9. Copy the secret into your secret store. The dashboard shows the secret one time.

WARNING: Do not commit a key. Anyone with the publisher key can publish packages within its permissions.

3. Create a package

Use a new directory. The example uses a POSIX shell, such as Bash or Zsh.

  1. Create the directory:
    mkdir private-package-demo
    cd private-package-demo
  2. Create package.json with this content:
    {
      "name": "@acme/hello-private",
      "version": "1.0.0",
      "type": "module",
      "exports": "./index.js",
      "files": ["index.js"],
      "publishConfig": { "registry": "https://registry.privatenpm.com/" }
    }
  3. Create index.js with this content:
    export const hello = () => 'Hello from my private package!';
  4. Create .npmrc with this content:
    @acme:registry=https://registry.privatenpm.com/
    //registry.privatenpm.com/:_authToken=${ACME_NPM_TOKEN}

The .npmrc file contains a variable reference, not a key. The scope route keeps public dependencies on npmjs.org.

4. Publish the package

Before you start, put the publisher key in the ACME_NPM_TOKEN environment variable through your secret store.

  1. Examine the package files:
    npm pack --dry-run
    The file list must contain index.js and package.json, with no secrets.
  2. Publish the package:
    npm publish
    The output ends with + @acme/[email protected].
  3. Open Registry → Packages. The package page shows version 1.0.0.

If that version already exists, increase the version in package.json. Published versions cannot change.

5. Install with a download key

Use a separate project and a separate read-only key to test recipient access.

  1. On the shared registry card, open Manage keys.
  2. Click New download key.
  3. Under Access rule, choose Selected packages and select your package.
  4. Create the key and store the secret.
  5. Replace ACME_NPM_TOKEN in your shell environment with the download key.
  6. Create a separate project:
    cd ..
    mkdir private-package-consumer
    cd private-package-consumer
    npm init -y
  7. Create the same .npmrc file in this new project.
  8. Install the package with an empty cache:
    npm install @acme/[email protected] --ignore-scripts --cache ./empty-cache
  9. Run the package:
    node --input-type=module -e "import { hello } from '@acme/hello-private'; console.log(hello())"
    The terminal prints Hello from my private package!.

If a command fails

  • E401: Check the token variable, registry host and key. Use the authentication checklist.
  • E403: Check the scope reservation, key restrictions and version number.
  • pnpm or Yarn: Use the package-manager instructions. Their credential settings differ.
  • Release-age policy: Your package manager can reject a new version. Keep your policy and retry after its waiting period.

Choose the next step

READY WHEN YOU ARE

Put private packages to work.