yarn
Verified against Yarn 4.18 (Yarn Modern / Berry). For Yarn Classic 1.x see the bottom of this page.
Quick start
export VLT_TOKEN=<your token>
yarn config set npmRegistryServer "https://registry.vlt.io/acme/npm/"yarn config set npmAlwaysAuth trueyarn config set npmAuthToken "\${VLT_TOKEN}"Then yarn install as usual.
The config file
Yarn keeps everything in .yarnrc.yml in your project root:
# all public npm packages come from your account mirrornpmRegistryServer: 'https://registry.vlt.io/acme/npm/'npmAlwaysAuth: truenpmAuthToken: '${VLT_TOKEN}'
# your own packages come from your main registrynpmScopes: acme: npmRegistryServer: 'https://registry.vlt.io/acme/main/' npmPublishRegistry: 'https://registry.vlt.io/acme/main/' npmAlwaysAuth: true npmAuthToken: '${VLT_TOKEN}' npmMinimalAgeGate: 0Notes on that file, all of which matter:
- Scope keys under
npmScopesare written without the@:acme, not@acme. npmAlwaysAuth: trueis required — Yarn otherwise omits the token on some requests and you get a401.npmRegistryServeris used for installing.npmPublishRegistryis used for publishing, and Yarn will not fall back tonpmRegistryServerfor publishes. Set both.npmMinimalAgeGate: 0is explained below — you want it on any registry you publish to.${VLT_TOKEN}is expanded from the environment, so this file is safe to commit.
Install from the npm mirror
yarn add abbrevTo move an existing project onto the mirror:
rm -rf yarn.lockyarn installInstall from your main registry
yarn add @acme/my-packagePublic packages
Public packages on main install without a token — the registry alone
is enough, with no npmAuthToken or npmAlwaysAuth:
npmScopes: acme: npmRegistryServer: 'https://registry.vlt.io/acme/main/' npmMinimalAgeGate: 0Publish to main
With npmPublishRegistry set as above:
yarn install # yarn refuses to publish without an up-to-date lockfileyarn npm publishAdd --access public for a package anyone can install.
The yarn install is not optional. Without a lockfile entry for your
own workspace, yarn npm publish aborts before it uploads anything:
Internal Error: @acme/my-package@workspace:.: This package doesn't seem to bepresent in your lockfile; run "yarn install" to update the lockfileWith 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.
You can also target the registry from package.json instead of
.yarnrc.yml:
{ "name": "@acme/my-package", "version": "1.0.0", "publishConfig": { "registry": "https://registry.vlt.io/acme/main/" }}Log in instead of using a token
yarn npm login --web-login --always-authRequires Yarn 4.12.0 or newer. The --web-login flag is mandatory
here: without it yarn npm login prompts for a username and password,
which this registry does not support. Yarn only attempts web login
automatically for npmjs itself.
Useful variants:
yarn npm login --web-login --scope acme # log in to the scope's registryyarn npm login --web-login --publish # log in to the publish registryyarn npm login writes the token to your home config, never to
the project.
On Yarn 4.0–4.11, or Yarn 2 and 3, there is no web login at all.
Either upgrade (yarn set version stable) or put a token in
.yarnrc.yml as shown above.
If Yarn ever drops to a Username: prompt, the web handshake failed
and it fell back to the legacy flow — that is not a prompt you can
satisfy.
Brand-new versions are hidden for 24 hours
Yarn 4 ships a supply-chain protection called npmMinimalAgeGate,
defaulting to 1440 minutes (24 hours). Any version published more
recently than that is skipped, so right after your first publish you
get:
YN0016: The version for tag "latest" is quarantined, and no lower version is availableSet it to 0 for your own registry:
npmScopes: acme: npmMinimalAgeGate: 0It must go under npmScopes.<scope>. A top-level
npmMinimalAgeGate: 0 is ignored for scoped packages — verified.
Scoping it this way also keeps the protection switched on for
everything coming from the public npm mirror, which is what you want.
Selecting a Yarn version
Use 4.12.0 or newer — that is the floor for browser login.
stable is well past it:
corepack use yarn@stable # records packageManager in package.jsonor set it directly:
{ "packageManager": "yarn@4.18.0" }yarn set version stable does the same thing without corepack. 4.18.0
is the current release; there is no Yarn 5.
Gotchas
npmPublishRegistryis mandatory for publishing. With onlynpmRegistryServerset,yarn npm publishgoes toregistry.yarnpkg.comand fails with a 404.- Run
yarn installbeforeyarn npm publish, or Yarn errors withThis package doesn't seem to be present in your lockfile. npmMinimalAgeGatemust be per-scope. See above.- An
npmScopesentry withoutnpmRegistryServersilently routes that scope toregistry.yarnpkg.com. The key defaults to npmjs rather than inheriting your top-levelnpmRegistryServer, so a scope block that sets onlynpmAuthTokenwill fetch from the wrong registry and reportPackage not found. Always setnpmRegistryServerinside every scope block. npmAlwaysAuthmust live in the same block as the token. A top-levelnpmAlwaysAuth: trueis ignored when the token comes from annpmScopesornpmRegistriesentry.- Yarn Berry does not read
.npmrcat all. If you are migrating from npm, the token in your.npmrcis invisible to Yarn 2+; it must be in.yarnrc.yml. - An unset variable is a hard error, unlike npm:
${VLT_TOKEN}with nothing set fails withEnvironment variable not found. Use${VLT_TOKEN:-}if you want it to fall back to empty. There is no${VAR:+...}form. yarn config setprintsSuccessfully set ... to undefinedwhen writing nestednpmRegistries[...]keys. The file is written correctly — the message is just wrong.- Yarn blocks plain
http://registries unless listed inunsafeHttpWhitelist. Not an issue forhttps://registry.vlt.io/, but it will bite you against a local registry. - Scope keys in
npmScopesomit the leading@.
Yarn Classic (1.x)
Yarn 1 is end-of-life; prefer Yarn 4. If you must:
yarn config set registry https://registry.vlt.io/acme/npm/yarn config set @acme:registry https://registry.vlt.io/acme/main/Yarn Classic reads auth tokens from .npmrc, so add:
//registry.vlt.io/acme/npm/:_authToken=${VLT_TOKEN}//registry.vlt.io/acme/main/:_authToken=${VLT_TOKEN}