Yarn
Yarn is supported read-only — Nub reads the Yarn lockfile (Classic v1 and Berry v2+) to install and run a project, but never writes it. Treat a Yarn project as something Nub consumes, not maintains.
Yarn is supported read-only. Install and run work; any command that would rewrite yarn.lock refuses before the engine touches anything:
$ nub add lodash
Error: nub add: refusing to modify yarn.lock —
adding a dependency re-resolves and rewrites yarn.lock
Run it with yarn directly:
yarn add lodashKeep using yarn for anything that changes the dependency graph.
Both formats are read:
- Classic —
yarn.lockwith no__metadatablock (Yarn 1.x). - Berry — the
__metadata/versionformat (Yarn 2+).
Configuration
| Feature | yarn | nub | Notes |
|---|---|---|---|
dependencies / devDependencies | Supported | Supported | |
optionalDependencies | Supported | Supported | |
peerDependencies / peerDependenciesMeta | Supported | Supported | |
resolutions | Supported | Supported | |
dependenciesMeta.*.built | Supported | Supported | |
packageExtensions | Supported | Supported | |
packageManager | Supported | Supported | |
workspace: protocol | Supported | Supported | |
npm: alias | Supported | Supported | |
portal: / patch: | Supported | Supported | |
workspaces | Supported | Supported | |
| workspace selectors | Supported | Partially supported. No git-since ([ref]) selector.No git-since ([ref]) selector. | No git-since ([ref]) selector. |
.npmrc | Supported | Supported | |
.yarnrc.yml | Supported | Partially supported. Per-host proxies and the layout keys are not read; PnP installs are refused.Per-host proxies and the layout keys are not read; PnP installs are refused. | Per-host proxies and the layout keys are not read; PnP installs are refused. |
.yarnrc | Supported | Partially supported. Registry and auth keys only.Registry and auth keys only. | Registry and auth keys only. |
npm_config_* | Supported | Supported | |
YARN_* | Supported | Partially supported. Reads the registry, auth token/ident, CA file, proxy, and strict-SSL env values; map-shaped and scoped env config is not translated.Reads the registry, auth token/ident, CA file, proxy, and strict-SSL env values; map-shaped and scoped env config is not translated. | Reads the registry, auth token/ident, CA file, proxy, and strict-SSL env values; map-shaped and scoped env config is not translated. |
yarn.lock | Supported | Partially supported. Read-only; writes refused.Read-only; writes refused. | Read-only; writes refused. |
nodeLinker | Supported | Not supported. Set the neutral .npmrc key instead; pnp is refused outright.Set the neutral .npmrc key instead; pnp is refused outright. | Set the neutral .npmrc key instead; pnp is refused outright. |
supportedArchitectures | Supported | Supported. Filters optional/platform deps for the declared os/cpu/libc.Filters optional/platform deps for the declared os/cpu/libc. | Filters optional/platform deps for the declared os/cpu/libc. |
| mTLS client cert/key | Supported | Supported. File-path (httpsCertFilePath / httpsKeyFilePath) and per-host networkSettings forms.File-path (httpsCertFilePath / httpsKeyFilePath) and per-host networkSettings forms. | File-path (httpsCertFilePath / httpsKeyFilePath) and per-host networkSettings forms. |
npmAlwaysAuth | Supported | Supported. Attaches credentials to cross-origin tarball requests too.Attaches credentials to cross-origin tarball requests too. | Attaches credentials to cross-origin tarball requests too. |
Running a Yarn project
nub install # reads yarn.lock, links node_modules, runs lifecycle scripts
nub ci # frozen install: yarn.lock is law; drift is a hard error
nub run <script> # runs package.json scripts
nubx <bin> # one-off binary executionTop-level resolutions in package.json is honored — Nub applies it the way Yarn does. Top-level overrides is npm and Bun's pin field; Yarn ignores it, and so does Nub under a Yarn incumbent — put pins in resolutions. The packageManager field is what tells Nub the project is a Yarn project.
Refused commands
Run these with yarn:
nub add <pkg> # → yarn add
nub remove <pkg> # → yarn remove
nub update # → yarn upgrade
nub dedupe # → yarn dedupeThe same gate fires on an install / ci that would rewrite the lockfile rather than just read it: a project that declares Yarn but has no yarn.lock yet, nub install --force / --no-frozen-lockfile / --lockfile-only, or a yarn.lock that no longer satisfies package.json. Run yarn install for those.
There is no path that converts to yarn.lock. The nub import command produces a pnpm-lock.yaml:
$ nub import # in a yarn project
Imported 2 packages from yarn.lock to pnpm-lock.yamlnub pm use yarn is a different surface
The nub pm use yarn command is the meta-manager command: it fetches and pins classic (v1) Yarn via the packageManager field and aligns the lockfile, converting a foreign one to a classic yarn.lock. (It refuses only the cases it can't convert faithfully — an existing Berry yarn.lock, a binary bun.lockb, or a workspace:-protocol graph.) That declaration-and-pin flow is separate from the read-only install engine described on this page, which never rewrites an existing yarn.lock.
Config files
Nub reads .npmrc for registry, auth, scopes, CA, and proxy settings. In a Yarn-incumbent project, Nub also reads a small .yarnrc.yml subset that maps cleanly onto its existing registry and resolution model:
npmRegistryServerbecomes the default registry.npmScopes.<scope>.npmRegistryServerbecomes a scoped registry.npmAuthTokenandnpmAuthIdentare applied when they can be attached to a known registry, includingnpmRegistriesentries.- Scope-level auth (
npmScopes.<scope>.npmAuthToken/npmAuthIdent) is applied only when that scope has its own unique customnpmRegistryServer. Scope auth with no custom registry, with a shared registry, or with a registry that also has annpmRegistriesentry is skipped rather than widened into registry-wide credentials. httpsCaFilePathbecomes the CA file, andnetworkSettings.<host>.httpsCaFilePathbecomes the per-host CA.httpProxy/httpsProxyset the proxy, andenableStrictSslmaps to strict-SSL.packageExtensionsis merged the same way pnpm's is, anddependenciesMeta.*.builtgates which packages run build scripts.YARN_NPM_REGISTRY_SERVER,YARN_NPM_AUTH_TOKEN,YARN_NPM_AUTH_IDENT, and the top-level CA, proxy, and strict-SSL env values are recognized above.yarnrc.ymlfor the same subset. Top-level auth env values attach when the env surface also supplies the registry they belong to; scoped and map-shaped Yarn env config is not translated.
Layout settings are not in that subset. Yarn's nodeLinker, nmHoistingLimits, and nmMode have no effect under Nub, and neither does YARN_NODE_LINKER — see resolution versus layout.
The same brand boundary applies as everywhere else: .yarnrc.yml is read only when the project is actually Yarn-owned, by packageManager: "yarn@..." or a Yarn lockfile. Nub-identity projects do not consume Yarn config.
# .yarnrc.yml — supported subset in a Yarn-incumbent project
npmRegistryServer: https://registry.internal/
npmScopes:
myorg:
npmRegistryServer: https://npm.myorg.dev/
npmAuthToken: "<token>"
npmRegistries:
"https://npm.myorg.dev":
npmAuthIdent: "user:pass"Nub reads the global ~/.yarnrc.yml plus any project .yarnrc.yml files from the workspace root down to the current project directory; nearer project files win. The support is intentionally narrow. Still ignored: per-host networkSettings proxies (the proxy Nub applies is process-wide), constraints, plugins, patch-folder config, and Yarn cache layout.
Classic .yarnrc (Yarn 1) gets the same basic treatment for its core registry and auth fields. Its keys are already npmrc-shaped, so Nub reads them directly:
# .yarnrc — supported core fields in a Yarn-incumbent project
registry "https://registry.internal/"
"@myorg:registry" "https://npm.myorg.dev/"
"//npm.myorg.dev/:_authToken" "<token>"Discovery mirrors classic Yarn: the global ~/.yarnrc plus any project .yarnrc files from filesystem root down to the current directory, nearer files winning. Only the default registry, scoped registries, and registry-keyed or top-level auth (_authToken / _auth) are read; every other classic key — network-timeout, save-prefix, yarn-offline-mirror, --flag argument lines, and so on — is ignored.
Node linkers
Yarn's nodeLinker does not select the layout Nub installs. A Yarn-owned project uses the neutral .npmrc key or the CLI flag instead.
# .npmrc — flat, npm-style node_modules
node-linker=hoistedPlug'n'Play is the exception, and it is a refusal rather than an ignored preference: a PnP project has no node_modules tree for Nub to install into. Yarn Berry defaults to PnP when nodeLinker is absent, so both nub install and nub ci abort before mutation with ERR_NUB_PNP_UNSUPPORTED. Set nodeLinker: node-modules to install with Nub.
Nub-the-runtime fully supports Plug'n'Play. If a project was already installed by Yarn in PnP mode, Nub can run it — nub <file>, nub run, and nubx honor .pnp.cjs across all supported Node versions. What Nub cannot do is produce a PnP install. So the supported workflow for a PnP project is: install with yarn, run with nub. See Plug'n'Play resolution for how Nub resolves a PnP project at runtime.
Gaps
Nub does not fully support these Yarn settings:
- Per-host
networkSettingsproxies — the proxy Nub applies is process-wide, not per registry host. - Layout settings —
nodeLinker,nmHoistingLimits,nmMode, andYARN_NODE_LINKERhave no effect. Pick a layout in.npmrcinstead. - Yarn PnP (
nodeLinker: pnp) — bothnub installandnub ciabort before mutation withERR_NUB_PNP_UNSUPPORTED. Install with Yarn and run with Nub, or selectnodeLinker: node-modules.
Bun
When Bun is the incumbent, Nub installs against it — Bun's text lockfile round-trips byte-for-byte, its trusted-dependencies list gates build scripts, and overrides, resolutions, patches, and catalogs all resolve Bun's way.
The virtual store
How Nub's default linker works — one symlink per package into a machine-global store, with install-time phantom detection and per-package ejection — its warm-install performance, and the flat and project-local opt-outs.