Skip to content

Publish to GitHub Packages

Automated publishing of packages to GitHub Packages using GitHub Actions on version tags.

When to use

Use this workflow when you want npm packages published to GitHub Packages automatically on version tags, keeping the entire release pipeline within GitHub's ecosystem.

The pattern

1. GitHub Action workflow

Create .github/workflows/publish-to-github-packages.yaml:

yaml
name: Publish to GitHub Packages

on:
  push:
    tags:
      - "v*"

jobs:
  publish-to-github-packages:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://npm.pkg.github.com"
          scope: "@your-org"
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build
        run: npm run build
      
      - name: Publish
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

2. Package configuration

Configure package.json:

json
{
  "name": "@your-org/package-name",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/"
  }
}

3. Release process

  1. Update version: npm version patch|minor|major
  2. Push with tags: git push --follow-tags
  3. GitHub Action automatically publishes

A complete package.json with all required fields:

json
{
  "name": "@myorg/my-library",
  "version": "1.0.0",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "test": "jest"
  },
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/myorg/my-library.git"
  }
}

Trade-offs

  • Tag triggers vs branch triggers: Tag triggers publish only explicit releases. Branch triggers risk publishing on every commit.
  • Scoped packages: GitHub Packages requires scoped names matching the repository owner (@your-org/package-name).
  • GITHUB_TOKEN vs PAT: The built-in GITHUB_TOKEN works for same-org publishing. Cross-org publishing requires a personal access token.

See also

  • GitHub: GitHub CLI, Actions, PRs, and CI workflows.