Run a single command with project-pinned Node.js and pnpm versions, without changing the current shell.
nvmc is a small command runner for frontend projects. It reads Node.js and pnpm versions from the project's .npmrc, prepares the required runtimes when needed, and applies them only to the command wrapped by nvmc.
- Temporarily uses a project-pinned Node.js version for one command.
- Temporarily uses a project-pinned pnpm version for one command.
- Keeps the interactive shell and global
node/pnpmunchanged. - Works on Windows, macOS, and Linux.
- Keeps nested
pnpmcalls on the pinned pnpm version. - Downloads and caches missing Node.js and pnpm CLI versions automatically.
- Uses atomic cache installs to tolerate interrupted downloads and concurrent CI jobs.
- Does not replace pnpm store behavior; existing pnpm store settings still apply.
The examples below use nvmc. Install it globally once:
npm install -g @fexd/nvmcIf global installation is not preferred, replace nvmc in the examples with npx -y @fexd/nvmc.
Initialize project versions:
nvmc init --node 20.19.5 --pnpm 9.15.9Or edit .npmrc directly:
nvmc-node=20.19.5
nvmc-pnpm=9.15.9Then prefix commands that need the project Node.js or pnpm version:
nvmc node scripts/build.js
nvmc pnpm install
nvmc pnpm run buildIn package.json scripts, rewrite commands the same way. For example, change pnpm run build to nvmc pnpm run build.
The package includes a migration skill for coding agents:
skills/migrate-to-nvmc/SKILL.md
Ask an agent to use it like this:
Read the migrate-to-nvmc skill from the nvmc package. Infer the project's Node.js and pnpm versions from evidence, ask me to confirm them, then update .npmrc and package.json scripts to use nvmc.
The skill asks agents to inspect package.json, .npmrc, pnpm-lock.yaml, .nvmrc, .node-version, and related evidence before editing files.
nvmc itself supports Node.js 12.17 or newer.
For npx -y @fexd/nvmc, the host npm should be 7 or newer. In practice, Node.js 16 or newer is recommended for the host runtime.
If the host still uses npm 6, install nvmc globally once and use the shorter command in scripts:
npm install -g @fexd/nvmc
nvmc versionThe target Node.js version managed by nvmc can be older than the host runtime, as long as that Node.js release exists for the current platform and the project itself can run on it.
nvmc doctor
nvmc node -v
nvmc pnpm -vnvmc init can update one or both versions:
nvmc init --node 20.19.5
nvmc init --pnpm 9.15.9Configure project versions in .npmrc:
nvmc-node=20.19.5
nvmc-pnpm=9.15.9nvmc-node: Node.js version used by wrapped project commands.nvmc-pnpm: pnpm version used by wrapped project commands.
{
"scripts": {
"nvmc:versions": "nvmc doctor && npm run nvmc:node && npm run nvmc:pnpm",
"nvmc:node": "nvmc node -v",
"nvmc:pnpm": "nvmc pnpm -v",
"install:deps": "nvmc pnpm install",
"build": "nvmc pnpm run build"
}
}nvmc pnpm prepends a pinned pnpm shim to the child process PATH, so nested pnpm calls keep using the pnpm version from .npmrc.
{
"scripts": {
"dev": "nvmc pnpm exec concurrently \"pnpm --filter @app/web dev\" \"pnpm --filter @app/server dev\""
}
}For cross-platform scripts, use plain pnpm inside nested commands. Do not hard-code pnpm.cmd.
When a command runs, nvmc:
- Finds the project root from the current directory.
- Reads
nvmc-nodeandnvmc-pnpmfrom.npmrc. - Checks whether the requested Node.js and pnpm CLI versions already exist in cache.
- Downloads and extracts missing versions.
- Starts the target command with the pinned Node.js executable.
- Injects a temporary
PATHonly for that command and its child processes.
After the command exits, the temporary environment disappears. The current shell's global node and pnpm versions do not change.
Default cache locations:
- Windows:
%LOCALAPPDATA%\nvmc - macOS:
~/Library/Caches/nvmc - Linux:
${XDG_CACHE_HOME:-~/.cache}/nvmc
Override the cache root with NVMC_HOME:
NVMC_HOME=/path/to/cache nvmc doctorThe cache stores Node.js distributions, pnpm CLI files, downloaded archives, and small shims. Project dependencies still use pnpm's own store.
Default sources:
- Node.js:
https://nodejs.org/dist - pnpm:
https://registry.npmjs.org
Mirror environment variables:
NVMC_NODE_MIRROR=https://nodejs.org/dist
NVMC_NPM_REGISTRY=https://registry.npmjs.orgThe current scope is intentionally focused on Node.js project commands:
- Node.js: pinned runtime version.
- pnpm: pinned package-manager version.
- npm / yarn: may be considered later as similar Node.js package managers.
nvmc does not manage JDK, Android SDK, Python, or other non-Node.js runtimes.