Corepack-style shims
Optional shims for bare package-manager commands. Install them and a bare pnpm, npm, or yarn command routes through Nub to the package manager your project pins, with no extra Node process in front.
Default Nub usage needs no shims: nub install, nub add, and nub run work on Nub's own engine, and the pin tells them which package manager's lockfile and config to follow. The shims run the exact pinned release for a bare pnpm, npm, or yarn command, whether you type it or a tool you don't control invokes it.
$ nub pm shimnub pm shim: 6 entries in ~/.local/share/nub/shims (6 created)PATH: added ~/.local/share/nub/shims to PATH (~/.zshrc) — restart your shell$ which pnpm~/.local/share/nub/shims/pnpm$ pnpm --versionpnpm@9.5.0 (via nub shim)Installing... (4 MB)Installed in 0.8s9.5.0
Each shim is a hardlink to the Nub binary, so no Node process starts in front of the package manager. On a cold cache the first command provisions the pinned version, then starts its launcher under the project's Node. The dim (via nub shim) line names the manager and version, and goes to stderr so piped stdout stays clean.
pnpm 12 ships as a native binary, and the shim runs it the way Corepack does: pnpm's own launcher downloads the binary on first use and keeps it beside the cached package, so later runs need no network. From pnpm 12.11.0 that download follows the registry and credentials in .npmrc. Earlier 12.x releases ignore .npmrc, so point them at a private mirror with COREPACK_NPM_REGISTRY, and COREPACK_NPM_TOKEN if it needs auth.
The shims live in the first of these directories:
$XDG_DATA_HOME/nub/shims— when that variable is set%LOCALAPPDATA%\nub\shims— Windows~/.local/share/nub/shims
The shims do not choose the manager; the packageManager pin in package.json does. Set it with nub pm use, which never touches your PATH.
Strict by default
In a pinned project, a shim refuses to run a different package manager, which would write a competing lockfile and node_modules. The error names the command to run instead:
$ yarn add react # ❌ wrong package manager for this project
nub: the nub package-manager shims on your PATH (installed via
`nub pm shim`) intercepted this.
This project pins pnpm (via package.json#packageManager) — refusing to
run yarn.
A different package manager here would write a competing lockfile
and node_modules.
run instead: pnpm add react
to bypass: invoke the system yarn by absolute path,
or remove the shims: nub pm unshimSome commands fall through to the system tool whatever the pin, so npm create vite works in a pnpm project:
- The
npxandpnpxcommands, and theinit,create,dlx, andexecverbs of every manager - Commands that never touch the project: global installs (
npm install -g) and registry and account commands such asnpm login,npm whoami, andnpm view - A package manager that a lifecycle script spawns during an install
npm publish still refuses, because it packs the project.
Missing system manager
An unpinned command falls through to the system manager. When there is none, as on a fresh machine or in a minimal container, the shim runs a default instead: the version family the committed lockfile implies, or the registry latest without one. It names the choice on stderr and writes no pin.
A resolved latest is remembered for 24 hours, and the last resolved version is reused when the registry is unreachable.
Running npm installs on Nub's engine
One opt-in routes npm's two install verbs to Nub's engine instead of the pinned npm:
nub pm shim --route-installs # turn routing on
nub pm shim --no-route-installs # turn it off, keep the shimsWith routing on, a bare npm ci in a project with a package-lock.json runs nub ci, and a bare npm install runs nub install, from the same lockfile:
$ npm ci
npm ci → nub ci (via nub shim)Every other npm command runs the real npm with the argv as typed. For the two install verbs, the input decides:
| npm input | Routed install |
|---|---|
--ignore-scripts | Translated |
--omit=dev, --production, NODE_ENV=production | Translated |
--omit=optional | Translated |
--include | Translated; wins over --omit in either order, as in npm |
--no-audit, --no-fund, --prefer-offline, log-level and progress flags | Accepted and ignored |
--legacy-peer-deps, --workspace, --prefix, --no-package-lock | Not routed; runs the real npm |
| A named package, a global install | Not routed; runs the real npm |
An npm install spawned by a lifecycle script during an install | Not routed; runs the real npm |
A routed install runs every lifecycle script, as npm does, under the node on PATH. It consults no Node pin and provisions nothing, and it hands the scripts NODE_ENV=production exactly when dev dependencies are omitted. An ignore-scripts=true in the project or user .npmrc, or npm_config_ignore_scripts in the environment, is honored, and --ignore-scripts=false on the command line outranks it.
Removing the shims
The nub pm unshim command deletes the shim directory and the PATH block, restoring the previous pnpm. It also removes install routing.
$ nub pm unshim
nub pm unshim: removed /Users/you/.local/share/nub/shims
PATH: removed the shims block from /Users/you/.zshrcPackage meta-manager
Provision and run the package manager your project pins, as corepack does, in native Rust. The exact pnpm, npm, or yarn release is fetched, verified, cached, and run on the project's Node.
Config referencenub.jsonc
The project file that configures Nub's runtime, dependency installs, and temporary package runs.