packall
Guides

Private registries

Read from Artifactory, Nexus or a scoped internal registry, with .npmrc credentials.

Point it somewhere else

packall react@19.2.8 --registry https://artifactory.corp/api/npm/npm-remote/

Without --registry, the registry comes from your .npmrc — read the way npm reads it.

Which registry actually gets used

Highest first:

  1. --registry <url>
  2. NPM_CONFIG_REGISTRY / npm_config_registry in the environment — the registry only
  3. --npmrc <path>
  4. $NPM_CONFIG_USERCONFIG
  5. ./.npmrc in the current directory
  6. ~/.npmrc

The environment outranks --npmrc, and npm run / pnpm run set it. Both export npm_config_registry into the scripts they run, so packall invoked from a package.json script takes your package manager's registry rather than the one in the file you named. A correct-looking .npmrc then produces Package "x" was not found on https://registry.npmjs.org/, or Cannot reach registry https://registry.npmjs.org/ on a network that cannot see it.

This matches npm's own precedence — the environment beats every config file. Pass --registry to settle it, or run the binary directly rather than through a script.

Only the default registry is affected. Credentials always come from the files, and a @scope:registry line still wins for its own scope, because the scope is consulted before the default is.

Credentials

Per-scope registries, _authToken, _auth and username/_password are all supported, with ${VAR} expansion:

.npmrc
registry=https://artifactory.corp/api/npm/npm-remote/
@acme:registry=https://artifactory.corp/api/npm/npm-local/
//artifactory.corp/api/npm/:_authToken=${NPM_TOKEN}

--npmrc <path> reads a specific file instead of searching.

Credentials never appear in output. The Authorization header is redacted in anything the run prints, including the reproducible command at the end.

Certificates

An internal registry is usually fronted by a certificate signed by a CA that Node's bundled trust store has never heard of. The .npmrc keys npm uses for that are read here too — cafile, ca / ca[], and strict-ssl:

.npmrc
registry=https://artifactory.corp/api/npm/npm-remote/
cafile=/etc/ssl/certs/corp-root-ca.pem

The CA is added to the system store rather than replacing it, so a bundle containing only your internal CA is enough. NODE_EXTRA_CA_CERTS works as well — Node loads it before the run starts.

strict-ssl=false is honoured, and turns certificate verification off for every connection the run makes — including the tarballs whose integrity you are trusting the registry to have got right. Reach for cafile first.

Client certificates (npm's per-registry certfile / keyfile) are not supported.

GitLab and GitHub Packages

Both speak the npm protocol and need no special handling. GitLab's project-scoped endpoint works as written, including the ; comments its UI generates:

.npmrc
registry=https://gitlab.com/api/v4/projects/<id>/packages/npm/
; begin auth token
//gitlab.com/api/v4/projects/<id>/packages/npm/:_authToken=${GITLAB_TOKEN}
; end auth token

always-auth=true is not read, and is not needed — the token goes on every request including tarball downloads, which is what that key asks for. GitLab answers 404 on the registry root; the preflight check treats any answer below 500 as proof the host is alive.

Tarballs are served as a redirect into object storage, and redirects are followed. The credential is dropped when the redirect crosses to another origin, which is both a leak that would otherwise send your registry token to Google or AWS, and a hard failure — a pre-signed URL rejects a request carrying a second authentication mechanism. A redirect that stays on the registry's own host keeps the credential.

Do not pass --rewrite-tarball-host with GitLab. Its tarball URLs repeat the package name (…/packages/npm/@acme/thing/-/@acme/thing-1.0.0.tgz), and rewriting would rebuild the npm-standard path and 404. The default — use the URL the registry returned — is correct here.

GitHub Packages is the same, and is usually scope-based:

.npmrc
@owner:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

When tarball URLs point at the wrong host

Some proxy configurations return upstream tarball URLs they will not themselves serve — Artifactory handing back /npm-remote-cache/… when you configured /npm-remote/ is the common case. --rewrite-tarball-host fetches tarballs from --registry instead of the URL the registry returned.

packall react@19.2.8 --registry https://artifactory.corp/api/npm/npm-remote/ --rewrite-tarball-host

Timeouts and retries

--timeout is the ceiling on every network wait — connecting, the preflight check, and each request. It bounds how long a registry may stay silent, not how long a download may take, so raising it helps a slow registry and not a slow link.

packall --file package.json --timeout 30000 --retries 5

Retries apply to transient failures only: 5xx, 429 and dropped connections. A 404, an auth failure or an integrity mismatch is a considered answer and is not retried.

--concurrency sets how many requests run at once (default 10). Lower it if a registry is rate-limiting you.

In the browser runner, a private registry only works if it sends CORS headers. Most corporate Artifactory and Nexus instances do not, and a browser cannot bypass that. Run the command on a machine inside the network instead — the runner hands you the exact line.

On this page