vlt / docs

  • PricingBenchmarks (opens in new window)Community (opens in new window)Feedback
  • Overview
  • vlt
  • npm
  • pnpm
  • yarn
  • bun
  • deno
  • CI & Automation
  • Quick start
  • The config file
  • ${VLT_TOKEN} does not work in a project .npmrc
  • Option 1 — log in (recommended for laptops)
  • Option 2 — pass the token as an environment variable (recommended for CI)
  • Install from the npm mirror
  • Install from your main registry
  • Public packages
  • Publish to main
  • Log in
  • Gotchas
  1. Registry
  2. /
  3. Publishing
  4. /
  5. pnpm

pnpm

Configure pnpm for your vlt.io registries, and publish to main.

Verified against pnpm 10, 11 and 12.

pnpm 12 works with the npm mirror since 12.3.0

pnpm 12 releases before 12.3.0 rejected the mirror's metadata and failed with no version found for the latest tag. The fix landed upstream in pnpm/pnpm#14448 and shipped in pnpm 12.3.0 (September 2026), so any current 12.x works.

If you pinned pnpm 11 as a workaround, move back to 12:

Terminal
corepack use pnpm@latest

That writes the resolved exact version into packageManager.

Quick start

Terminal
export VLT_TOKEN=<your token>

pnpm config set registry https://registry.vlt.io/acme/npm/ --location=project
pnpm config set @acme:registry https://registry.vlt.io/acme/main/ --location=project

Then add auth by logging in through the browser:

Terminal
pnpm login --registry=https://registry.vlt.io/acme/npm/
pnpm login --registry=https://registry.vlt.io/acme/main/ --scope=@acme

Now pnpm install works.

The config file

pnpm reads registry and auth settings from .npmrc, same keys as npm. Commit the routing only, with no credentials:

INI
registry=https://registry.vlt.io/acme/npm/
@acme:registry=https://registry.vlt.io/acme/main/

Registry and auth keys belong in .npmrc; every other pnpm setting now lives in pnpm-workspace.yaml. pnpm before 11.10 ignores registry in pnpm-workspace.yaml when installing.

${VLT_TOKEN} does not work in a project .npmrc

Unlike npm, yarn, bun and deno, pnpm deliberately ignores ${...} placeholders in a repository .npmrc for registry, proxy and credential values. A file containing //registry.vlt.io/acme/npm/:_authToken=${VLT_TOKEN} sends no Authorization header at all — you get a 401 that looks like a bad token, with no warning explaining why.

This is a supply-chain fix (a malicious repo could otherwise redirect your token to a registry it controls), landed in pnpm 11.5.3, so it applies to every current version. Use one of the two options below instead.

Which option is available depends on the version, and there is one unlucky release with neither:

pnpm version${VLT_TOKEN} in project .npmrcpnpm_config_… env var
11.5.2 and olderworksnot supported
11.5.3blockednot supported
11.6.0 and newer 11.xblockedworks
12.xblockedworks

On any current pnpm (11.6.0+, all of 12.x), use pnpm login or the environment variable — never a placeholder in the project file.

Option 1 — log in (recommended for laptops)

Terminal
pnpm login --registry=https://registry.vlt.io/acme/npm/
pnpm login --registry=https://registry.vlt.io/acme/main/ --scope=@acme

Browser-based, and the credential is stored in your global pnpm config rather than in the repo.

Option 2 — pass the token as an environment variable (recommended for CI)

pnpm accepts any config key as a pnpm_config_-prefixed variable, which sidesteps the placeholder restriction entirely:

Terminal
env "pnpm_config_//registry.vlt.io/acme/npm/:_authToken=$VLT_TOKEN" pnpm install

Two notes:

  • Use env rather than export — the variable name contains /, : and ., which the shell will not accept in an assignment.
  • Needs pnpm 11.6.0 or newer. On older versions the variable is ignored and you get ERR_PNPM_FETCH_401 … No authorization header was set for the request.

In CI you can also write the auth lines to the user-level ~/.npmrc, where ${VLT_TOKEN} still expands — see CI & automation.

Install from the npm mirror

Terminal
pnpm add abbrev

To move an existing project onto the mirror, keep pnpm-lock.yaml — it stores no tarball URLs — and run pnpm install:

Terminal
pnpm install

Install from your main registry

Terminal
pnpm add @acme/my-package

Public packages

Public packages on main install without a token — the registry line alone is enough, with no auth line:

INI
@acme:registry=https://registry.vlt.io/acme/main/

Publish to main

JSON
{
  "name": "@acme/my-package",
  "version": "1.0.0",
  "publishConfig": {
    "registry": "https://registry.vlt.io/acme/main/"
  }
}
Terminal
pnpm publish

publishConfig.registry decides the destination, and in pnpm it is the strongest setting — it beats @acme:registry and even an explicit --registry flag, which is the weakest of the four. (npm resolves these in a different order, so don't assume a publish script behaves identically under both.) Add --access public for a package anyone can install.

Two flags you will probably want:

  • --no-git-checks — pnpm refuses to publish unless the git tree is clean and you are on the publish branch. Verified: an uncommitted file fails with ERR_PNPM_GIT_UNCLEAN.
  • --dry-run — pack and report without uploading.

With a personal token, every publish returns a one-time-password challenge with a vlt.io URL — open it, approve, re-run. A service token skips the prompt and is what you want in CI; see CI & automation.

Log in

Terminal
pnpm login --registry=https://registry.vlt.io/acme/main/ --scope=@acme

This uses the browser login flow and prints an authentication URL. --scope also records the scope-to-registry mapping for you. In current pnpm the credential is written to your global pnpm config, not to .npmrc.

pnpm token is not implemented in pnpm — it reports Not implemented in pnpm. Use the npm CLI directly. Manage tokens at vlt.io or with npm token.

Gotchas

  • pnpm 12 before 12.3.0 cannot install from the npm mirror. Those releases dropped every version whose metadata carried a field the new parser did not recognise. Fixed in pnpm/pnpm#14448 — use 12.3.0 or newer.
  • ${VAR} in a project .npmrc is ignored, silently. See above.
  • pnpm config set writes to your machine-global config by default. Always pass --location=project, or credentials end up in your user config unexpectedly. --location accepts only project and global — there is no user.
  • always-auth no longer exists in pnpm. Setting it produces an unrecognized-setting warning and does nothing; it isn't needed.
  • Trailing slashes must match between the registry URL and the auth line.
  • --npmrc-auth-file (alias --userconfig) points pnpm at a different .npmrc for auth. That file is treated as trusted, so ${VAR} expansion does work there — only use it in environments that build trusted repositories.

PreviousnpmNextyarn

On this page

  • Quick start
  • The config file
  • ${VLT_TOKEN} does not work in a project .npmrc
  • Option 1 — log in (recommended for laptops)
  • Option 2 — pass the token as an environment variable (recommended for CI)
  • Install from the npm mirror
  • Install from your main registry
  • Public packages
  • Publish to main
  • Log in
  • Gotchas
Edit this page

Deploy your package on vlt.io

Publish scoped and private packages, manage organizations and access, and give every developer and CI environment a consistent source for public and private JavaScript dependencies.

Publish now