npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gh-npm-auth-preinstall

v0.4.0

Published

Save yourself from 403s when installing private GitHub Packages. Pass one or more @scopes; the tool checks whether your gh auth can read them and walks you through fixing it if not.

Readme

gh-npm-auth-preinstall

Save yourself from 403 Forbidden when installing private GitHub Packages.

Pass one or more @scope arguments. The tool probes api.github.com with your current ~/.npmrc token and tells you whether you can read packages from those scopes. If you can't, it walks you through fixing it via the gh CLI and writes the refreshed token to ~/.npmrc.

Works on macOS, Linux, and Windows. Node 18+. See Platform support for specifics.

Install

Run it ad-hoc:

npx gh-npm-auth-preinstall @your-org
pnpm dlx gh-npm-auth-preinstall @your-org @another-org

Or add it to a project as a dev dependency + preinstall hook:

pnpm add -D gh-npm-auth-preinstall
// package.json
{
  "scripts": {
    "preinstall": "gh-npm-auth-preinstall @your-org || true"
  }
}

The || true keeps the very first install from failing before the binary is on disk. After that, the check runs on every install.

CLI

gh-npm-auth-preinstall @scope [@scope ...]

  -h, --help       Show help
  -v, --version    Print version
  -n, --dry-run    Detect problems but don't run gh or write ~/.npmrc
  -f, --force      Run even on CI / when GH_NPM_AUTH_SKIP is set

Scopes are positional. The leading @ is optional — gh-npm-auth-preinstall traild and gh-npm-auth-preinstall @traild are equivalent. Pass as many as you need. Duplicates and case differences are deduped.

If no scopes are passed, the tool prints a warning and exits 0 — it never errors on missing arguments.

What it does

  1. Reads your auth token from ~/.npmrc (line //npm.pkg.github.com/:_authToken=...), expanding ${ENV} references.
  2. For each scope, sends GET https://api.github.com/orgs/<scope>/packages?package_type=npm with the token. Falls back to /users/<scope>/packages if 404.
    • 200 → access works.
    • 401 → token missing or invalid.
    • 403 → token lacks read:packages scope or SSO is required for the org.
  3. If anything fails: checks that gh is installed, runs gh auth login or gh auth refresh --scopes read:packages, grabs the new token via gh auth token, and upserts the //npm.pkg.github.com/:_authToken line in ~/.npmrc.
  4. Re-probes. If 403s persist, prints SSO authorization guidance with the exact org URLs to authorize.

Independently of the auth flow, the tool also ensures ~/.npmrc contains node-options=--use-system-ca. npm and pnpm read that config and prepend it to NODE_OPTIONS for the install process and its lifecycle scripts, so subsequent installs trust the OS certificate store (Windows cert store, macOS Keychain, Linux ca-certificates). This matters behind corporate TLS-inspecting proxies. The option is appended to any existing node-options= line; if --use-system-ca is already present, the file is left alone. Requires Node 22.15+ / 23+ for --use-system-ca to take effect.

If gh isn't installed, prints platform-specific install instructions and exits non-zero.

CI / non-interactive environments

The tool auto-skips on CI. If CI=true (set by every major CI provider — GitHub Actions, GitLab, CircleCI, Travis, Vercel, Netlify, Buildkite, etc.), the tool exits 0 immediately with a one-line log and doesn't probe the registry. CI builds don't pay the network cost and don't break on first-run.

In CI, set up auth the normal way:

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

Manual control

| Knob | Effect | | -------------------------- | ----------------------------------------------------- | | CI=true | Auto-skips (default behaviour on every CI provider). | | GH_NPM_AUTH_SKIP=1 | Force skip anywhere — local, CI, sandbox, anywhere. | | --force / -f | Run even when CI is detected or GH_NPM_AUTH_SKIP is set. Useful for testing the CI bailout. | | CI=false or CI=0 | Treated as "not CI" — the tool runs normally. |

Platform support

| Platform | Status | Notes | | --- | --- | --- | | macOS | ✅ Tested | Primary dev target. brew install gh for the CLI. | | Linux | ✅ Works | Identical code path to macOS. apt / dnf / pacman instructions printed when gh is missing. | | Windows | ✅ Works | Resolves gh.exe on Windows (Node's spawn doesn't search PATHEXT, so this is explicit). Uses os.homedir()C:\Users\<name>\.npmrc. winget / scoop / choco instructions printed when gh is missing. chmod 0o600 on ~/.npmrc is a best-effort no-op on Windows. |

Terminal notes for Windows

ANSI colors render correctly in Windows Terminal, PowerShell 5+, and cmd.exe on Windows 10+. Older terminals (legacy cmd.exe pre-Win10 Anniversary) may show escape codes as garbage; set NO_COLOR=1 to disable colors.

Shell quirks

The CLI never invokes anything via a shell (spawn is called with shell: false), so spaces in paths, quoting, and shell metacharacters in tokens are all safe across platforms.

SSO orgs

If your org enforces SAML SSO, a personal access token (even with read:packages) won't work until you authorize it for the org. After running the tool, if you still see 403, the tool prints the exact SSO authorization URL for each affected org. Open it, click Authorize, and re-run.

Why not just npm login?

npm login --registry=https://npm.pkg.github.com works, but:

  • it doesn't tell you whether your token has the wrong scopes,
  • it doesn't help with SSO authorization,
  • it doesn't say which scopes you can or can't read,
  • it stores credentials in a way that surprises some pnpm setups.

This tool gives a focused, fast diagnostic + fix, then gets out of the way.

Development

pnpm install
pnpm build           # produces dist/index.js with a node shebang
pnpm typecheck
node ./dist/index.js --help

Tests

Tests use Node's built-in node:test runner via tsx (no Jest/Vitest).

pnpm test            # build + run full suite
pnpm test:unit       # parser, token, upsert, scope normalization — no network
pnpm test:cli        # spawn-based CLI tests (some hit api.github.com)
pnpm test:offline    # full suite with network tests skipped

Network tests verify the probe correctly classifies 401 from api.github.com for invalid tokens. Set GH_NPM_AUTH_OFFLINE=1 to skip them in airgapped environments.

License

MIT