npm / yarn / pnpm / bun
Avrea caches packages from the public npm registry so
that npm install, yarn install, pnpm install, and bun install resolve
from local storage on repeat runs. The cache serves the npm registry protocol,
so it works with any package manager that installs from the npm registry, not
only the npm CLI.
On Avrea runners
Section titled “On Avrea runners”The registry URL is pre-configured:
npm_config_registry="https://cache.avrea.com:8443/npm/"This applies to npm, pnpm, yarn classic (v1), and bun. Your workflow needs no changes:
jobs: build: runs-on: avrea-ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: 24 cache: 'npm' - run: npm ciManual setup
Section titled “Manual setup”npm config set registry https://cache.avrea.com:8443/npm/pnpm config set registry https://cache.avrea.com:8443/npm/yarn config set registry https://cache.avrea.com:8443/npm/Bun respects the npm_config_registry environment variable, so no bunfig.toml
is needed on Avrea runners. To opt in explicitly from a Bun project:
npm_config_registry="https://cache.avrea.com:8443/npm/"Or add to bunfig.toml:
[install]registry = "https://cache.avrea.com:8443/npm/"Private npm registries
Section titled “Private npm registries”Avrea caches private npm tarballs beside your runners for faster, lower-latency downloads across builds. Your registry checks access on every request, including cache hits. Private npm caching is opt-in.
Enable private packages
Section titled “Enable private packages”Enable private npm caching for your organization or repository in the console, or via the CLI:
avr settings set cache.npm-private-registry.enabled truePackage Manager Cache must remain enabled. Repository settings override organization settings.
Configure the scope and token
Section titled “Configure the scope and token”Configure the private scope in the project's .npmrc. The token can come from
a GitHub Actions secret or an OIDC exchange with your registry:
@example:registry=https://cache.avrea.com:8443/npm-proxy/registry.example.com///cache.avrea.com:8443/npm-proxy/registry.example.com/:_authToken=${NODE_AUTH_TOKEN}//registry.example.com/:_authToken=${NODE_AUTH_TOKEN}Replace @example and registry.example.com with your package scope and upstream
registry. Keep the literal ${NODE_AUTH_TOKEN} placeholder. For a stored token,
add a read-only token as the GitHub Actions secret PRIVATE_NPM_TOKEN and pass
it to the install step:
- run: npm ci env: NODE_AUTH_TOKEN: ${{ secrets.PRIVATE_NPM_TOKEN }}npm, pnpm, and bun read scoped registries and tokens from .npmrc, so the
same file works with pnpm install --frozen-lockfile and
bun install --frozen-lockfile. Yarn Berry (v2+) ignores .npmrc; configure
the scope in .yarnrc.yml instead:
npmScopes: example: npmRegistryServer: "https://cache.avrea.com:8443/npm-proxy/registry.example.com/" npmAuthToken: "${NODE_AUTH_TOKEN}"Only @example packages use this registry. Other packages keep using the public
npm cache. npm does not fall back between registries.
Short-lived tokens with OIDC
Section titled “Short-lived tokens with OIDC”Keep your registry's OIDC authentication step before the install step. GitHub
issues the workflow identity token; your registry exchanges it for a short-lived
registry access token. Pass that registry access token as NODE_AUTH_TOKEN.
Avrea forwards it to your registry for authorization, including on cache hits.
Configure your registry to trust the intended repository, workflow, and branch, and grant the mapped service account read access to the packages. Login and token exchange use the upstream service directly. If a login step writes credentials only for the upstream URL, also configure the proxy token entry shown above.
The following example uses Cloudsmith’s private npm registry and its official
action. The same pattern applies to other providers that support OIDC: exchange
the workflow’s identity for a registry access token, then pass it to npm as
NODE_AUTH_TOKEN.
permissions: contents: read id-token: writesteps: # After checkout and Node.js setup: - name: Authenticate to Cloudsmith uses: cloudsmith-io/cloudsmith-cli-action@69e169e2ad9bc9a1599c2dff464061a00fe9f8ba # v3.1.1 with: cli-version: "1.27.0" oidc-namespace: YOUR_WORKSPACE oidc-service-slug: YOUR_READ_ONLY_SERVICE verify-auth: "true" export-auth-token: "true" - run: | export NODE_AUTH_TOKEN="$CLOUDSMITH_API_KEY" npm ciFor an upstream URL of https://npm.cloudsmith.io/YOUR_WORKSPACE/YOUR_REPOSITORY/,
use this .npmrc, replacing the scope and path placeholders:
@example:registry=https://cache.avrea.com:8443/npm-proxy/npm.cloudsmith.io/YOUR_WORKSPACE/YOUR_REPOSITORY///cache.avrea.com:8443/npm-proxy/npm.cloudsmith.io/YOUR_WORKSPACE/YOUR_REPOSITORY/:_authToken=${NODE_AUTH_TOKEN}//npm.cloudsmith.io/YOUR_WORKSPACE/YOUR_REPOSITORY/:_authToken=${NODE_AUTH_TOKEN}No stored registry secret is needed for this flow. See Cloudsmith's OIDC setup guide for the provider and service-account configuration. The token must remain valid throughout the install; cached packages do not bypass token expiry.
Registries with a port or base path
Section titled “Registries with a port or base path”Preserve the upstream host, optional port, and base path after /npm-proxy/.
For https://registry.example.com:9443/team/npm/, use:
@example:registry=https://cache.avrea.com:8443/npm-proxy/registry.example.com:9443/team/npm///cache.avrea.com:8443/npm-proxy/registry.example.com:9443/team/npm/:_authToken=${NODE_AUTH_TOKEN}//registry.example.com:9443/team/npm/:_authToken=${NODE_AUTH_TOKEN}Match ports and paths exactly between the registry and token entries so npm attaches credentials to tarball requests.
Migrate an existing lockfile
Section titled “Migrate an existing lockfile”The same lockfile requirements apply to stored tokens and OIDC tokens. Avrea
does not automatically rewrite the lockfile before npm ci.
Regenerate the private packages' resolved URLs through the proxy on an Avrea
runner. Compare the resulting lockfile with the original: private resolved
URLs should use the intended /npm-proxy/ prefix, while versions and integrity
hashes must stay unchanged. Validate with a frozen install (npm ci,
pnpm install --frozen-lockfile, yarn install --immutable, or
bun install --frozen-lockfile) using a fresh package manager cache.
Running npm install --package-lock-only against an existing lockfile may retain
its old URLs. Do not use replace-registry-host=always: it can send private
packages to the default public cache instead of their scope registry.
Compatibility
Section titled “Compatibility”- Avrea runners only. The proxy address is not reachable from developer machines or other CI providers. Keep direct registry configuration and upstream lockfile URLs for those environments.
- HTTPS and bearer tokens. The registry must be publicly reachable with a certificate trusted by Avrea. Tokens travel through Avrea over HTTPS and are not persisted in package cache storage or organization settings.
- Same-origin tarballs. Tarball URLs must contain
/-/and end in.tgz. The initial tarball URL must use the registry host without a query string. Avrea follows up to three HTTPS redirects, including signed CDN download URLs used by registries such as Cloudsmith. Private-network registries are unsupported. Publishing and login use the upstream directly. - Cacheable responses. Tarballs need a strong ETag and a known, nonempty size within the configured limit (128 MiB by default). Other eligible downloads stream without being stored.
Private tarballs count toward the repository cache quota. Different repositories store separate copies.
Troubleshooting and rollback
Section titled “Troubleshooting and rollback”For 401 or 403, check the token's read permission, workflow environment
binding, matching .npmrc URL prefixes, and the repository's cache settings.
If installs succeed but bypass Avrea, check private resolved URLs and retry
with a fresh npm cache.
To roll back, restore the direct scope registry, token entry, and upstream lockfile URLs without changing versions or integrity. Verify a direct install before disabling private npm caching. Proxy-pinned lockfiles fail when the setting is disabled; they do not redirect upstream.