GitHub Packages
Documentation for GitHub Packages
Scope: Private package hosting for @neutrino-io scoped packages on GitHub Packages
Last updated: 2026-02-22
Note on package names: Earlier docs reference
@neutrino-io/authandpackages/auth/. The current package is@neutrino-io/ui-authatpackages/ui-auth/. Update references accordingly as additional packages are published to the registry.
Overview
The @neutrino-io scope is hosted on GitHub Packages (https://npm.pkg.github.com). Packages are:
- Access-controlled — only users with repository access can install
- Authentication-required — a GitHub PAT or
GITHUB_TOKENis needed - Automatically published — CI workflow triggers on push to
mainwhen package files change
Installing a Private Package
Prerequisites
- Repository collaborator access on
neutrino/nno-starter-app - A GitHub Personal Access Token (PAT) with
read:packagesscope
1. Generate a PAT
GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
→ Generate new token (classic)
→ Scopes: ✅ read:packages
→ Copy the token (starts with "ghp_")2. Configure the Registry
Option A — Global (recommended for local dev)
npm config set @neutrino-io:registry https://npm.pkg.github.com
npm config set //npm.pkg.github.com/:_authToken ghp_YOUR_TOKENOption B — Project .npmrc (recommended for team repos)
# .npmrc (do NOT commit your token — use the env var form)
@neutrino-io:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}export GITHUB_TOKEN=ghp_YOUR_TOKENOption C — Multiple scopes
# ~/.npmrc
@neutrino-io:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NEUTRINO_TOKEN}
@other-org:registry=https://registry.npmjs.org
//registry.npmjs.org/:_authToken=${NPM_TOKEN}3. Install
pnpm add @neutrino-io/ui-auth
pnpm add @neutrino-io/ui-auth@1.2.3 # specific versionCI/CD Integration
GitHub Actions
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://npm.pkg.github.com'
scope: '@neutrino-io'
- name: Install dependencies
run: pnpm install
env:
NODE_AUTH_TOKEN: ${{ secrets.PACKAGE_READ_TOKEN }}Add PACKAGE_READ_TOKEN to repository secrets:
Repository → Settings → Secrets and variables → Actions → New repository secret
Name: PACKAGE_READ_TOKEN
Value: PAT with read:packages scopeDocker
FROM node:20
ARG GITHUB_TOKEN
RUN echo "@neutrino-io:registry=https://npm.pkg.github.com" >> ~/.npmrc && \
echo "//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}" >> ~/.npmrc
RUN pnpm add @neutrino-io/ui-authPublishing a Package
Automated Publishing (CI)
The workflow at .github/workflows/publish-auth-package.yml publishes automatically when:
- Push is to the
mainbranch - Files in the target package directory have changed
- The version in
package.jsonhas not already been published
Workflow steps:
- Typecheck → Lint → Build → Test
- Extract version from
package.json - Check if version already exists in registry (skip if so)
- Publish to
https://npm.pkg.github.com - Create a GitHub Release with the version tag
The workflow uses the built-in GITHUB_TOKEN — no additional secrets required for publishing.
Publishing a New Version
# 1. Bump version in the package's package.json
# e.g. "1.0.0" → "1.0.1"
# 2. Commit and push to main
git add packages/ui-auth/package.json
git commit -m "chore: bump @neutrino-io/ui-auth to 1.0.1"
git push origin main
# Workflow runs automaticallyPackage Configuration (package.json)
{
"name": "@neutrino-io/ui-auth",
"version": "1.0.0",
"publishConfig": {
"registry": "https://npm.pkg.github.com",
"access": "restricted"
}
}Access setting: Use
"restricted"for private packages."public"makes the package publicly installable without authentication — only use that intentionally.
Access Control
| Role | Can install | Can publish |
|---|---|---|
| Repository collaborator | ✅ | Only via CI workflow |
| Organization member (if org repo) | ✅ | Only via CI workflow |
| External user (granted manually) | ✅ | ❌ |
To grant external access:
Repository → Settings → Packages → [package name] → Package access → Add user/teamTroubleshooting
| Error | Cause | Fix |
|---|---|---|
E401 Unable to authenticate | Token missing or expired | Regenerate PAT, check read:packages scope |
E404 Not Found | Registry not configured for @neutrino-io scope | Add @neutrino-io:registry to .npmrc |
E403 Forbidden | No package access | Ask maintainer to grant access |
Version already exists | Same version pushed twice | Bump version number |
packages: write permission error | CI token lacks publish permission | Enable packages: write in workflow permissions |
# Debug commands
npm config list # inspect current registry config
npm ping --registry=https://npm.pkg.github.com
npm view @neutrino-io/ui-auth --registry=https://npm.pkg.github.com
curl -H "Authorization: token ghp_YOUR_TOKEN" https://api.github.com/user/packagesSecurity Checklist
- Never commit PATs to version control
- Use
$\{GITHUB_TOKEN\}env var form in.npmrcfiles - Rotate tokens regularly
- Scope tokens to minimum required permissions (
read:packagesfor consumers) - Use
"access": "restricted"unless public distribution is intentional