Skip to content

GitHub Packages — Private npm Registry

We use GitHub Packages as our private npm registry for internal JavaScript packages, under the @subscribed-aps scope.

Background

This replaced our self-hosted Verdaccio instance. See ADR-0002 for the rationale.


Prerequisites

You need a classic GitHub personal access token (PAT) with the following permissions:

Permission Required for
read:packages Installing packages
write:packages Publishing packages

Create one at GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic).


Authentication

Add the scoped registry to your ~/.npmrc once so npm knows to route @subscribed-aps packages to GitHub Packages:

echo "@subscribed-aps:registry=https://npm.pkg.github.com" >> ~/.npmrc

Then log in:

npm login --scope=@subscribed-aps --auth-type=legacy --registry=https://npm.pkg.github.com

Enter your GitHub username and use your PAT as the password.


Installing packages

Once authenticated, install as normal — the scoped registry entry in ~/.npmrc handles routing automatically:

npm install @subscribed-aps/subscribed-cli

To install globally (e.g. the Subscribed CLI):

npm install -g @subscribed-aps/subscribed-cli

If you haven't set up ~/.npmrc, pass the registry flag explicitly:

npm install @subscribed-aps/subscribed-cli --registry=https://npm.pkg.github.com

Publishing a package

1. Remove the private field from package.json if present — GitHub Packages will reject private-flagged packages.

2. Add publishConfig and repository to package.json:

{
  "publishConfig": {
    "registry": "https://npm.pkg.github.com"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/subscribed-aps/<package-name>.git"
  }
}

3. Publish:

npm publish

Scoped package name

The name field in package.json must be scoped: @subscribed-aps/<package-name>. GitHub Packages will reject packages outside the organisation's scope.