Skip to main content

Publishing to GitHub Packages

GitHub Packages provides an npm registry tightly integrated with your GitHub repositories. It's ideal for organization-internal packages and packages tied to specific repos.

Overviewโ€‹

  • Packages are scoped to your GitHub user or organization (@owner/package-name)
  • Supports public and private packages
  • Authentication uses GitHub tokens (PAT or GITHUB_TOKEN)
  • Free for public repos; included storage for private repos with GitHub plans

Setting Up .npmrcโ€‹

Configure npm to use GitHub Packages for your scope:

@my-org:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

Place this .npmrc in your project root or user home directory.

Authenticationโ€‹

Personal Access Token (PAT)โ€‹

For local development, create a PAT with read:packages and write:packages scopes:

npm login --scope=@my-org --registry=https://npm.pkg.github.com

GITHUB_TOKEN in Actionsโ€‹

In GitHub Actions, use the built-in GITHUB_TOKEN:

env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
info

GITHUB_TOKEN has automatic permissions scoped to the current repository. For cross-repo access, use a PAT or fine-grained token stored as a repository secret.

Package.json Setupโ€‹

Your package name must match your GitHub owner scope:

{
"name": "@my-org/my-package",
"version": "1.0.0",
"publishConfig": {
"registry": "https://npm.pkg.github.com"
}
}

The publishConfig.registry field ensures npm publish targets GitHub Packages regardless of your global npm config.

Publishing Manuallyโ€‹

# Ensure .npmrc is configured
npm publish

Publishing via GitHub Actionsโ€‹

name: Publish Package

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://npm.pkg.github.com
scope: '@my-org'
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tip

Trigger publishing on GitHub Release events for a clean workflow: create a release in the UI or via gh release create, and the package publishes automatically.

Consuming GitHub Packagesโ€‹

To install packages from GitHub Packages in another project, add to .npmrc:

@my-org:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

Then install normally:

npm install @my-org/my-package

In CI/CDโ€‹

Set the token as an environment variable:

steps:
- uses: actions/setup-node@v4
with:
registry-url: https://npm.pkg.github.com
scope: '@my-org'
- run: npm ci
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Linking Packages to Repositoriesโ€‹

GitHub automatically links packages to repos when the repository field in package.json matches:

{
"repository": {
"type": "git",
"url": "https://github.com/my-org/my-repo.git"
}
}

This enables the package to appear in the repo's "Packages" sidebar on GitHub.