Skip to content

nrldcm/nvmv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nvmv — every nvm command on Windows, without admin rights

nvm use on Windows fails for a lot of us with a permission error. nvmv is a drop-in replacement for the whole nvm command line. It needs no elevation, no UAC prompt, and no changes to how you install Node versions.

Only five nvm commands ever needed admin, and they all fail for the same reason. nvmv implements those five itself and hands everything else to nvm.exe untouched, so nvmv <anything> behaves like nvm <anything> minus the UAC prompt.

Handled by nvmv — the ones nvm needs elevation for:

nvmv                     list installed versions, mark the active one
nvmv current             print just the active version
nvmv use 20              switch to the newest installed 20.x
nvmv use 20.16.0         switch to an exact version
nvmv use latest          switch to the newest release, if it is installed
nvmv use lts             switch to the newest installed LTS release
nvmv use newest          switch to the highest version installed
nvmv use                 switch to the version named in .nvmrc
nvmv 20                  shorthand for "nvmv use 20"
nvmv on / nvmv off       enable or disable version management
nvmv uninstall 20.16.0   remove a version, even the active one
nvmv reinstall 20.16.0   remove it, download it again, switch to it
nvmv doctor              check whether this machine can switch without admin

Forwarded to nvm.exe — these never needed admin in the first place:

nvmv install <version>   nvmv list available    nvmv arch
nvmv root [path]         nvmv proxy [url]       nvmv debug
nvmv node_mirror [url]   nvmv npm_mirror [url]  nvmv version
nvmv upgrade             nvmv subscribe <topic>

Because the forwarded commands keep nvm's own exit codes and output, you can alias nvm to nvmv and forget nvm was ever the thing that prompted you.

One gap: nvm's use accepts a trailing 32 or 64 to flip a version between its two builds. nvmv does not do that — it switches versions, not architectures — and it refuses the argument rather than ignoring it and leaving you on a build you did not ask for. nvmv install <version> <arch> still downloads either one, since that is forwarded straight to nvm.

Why nvm use asks for admin

nvm-for-windows does not move Node around when you switch versions. Every version lives under %NVM_HOME% (typically %LOCALAPPDATA%\nvm), like this:

%NVM_HOME%\v20.20.0\node.exe
%NVM_HOME%\v22.23.1\node.exe

What is actually on your PATH is a link, %NVM_SYMLINK% — commonly C:\nvm4w\nodejs. Switching versions just means repointing that link:

C:\nvm4w\nodejs  ->  %NVM_HOME%\v20.20.0

nvm creates that link as a symbolic link, and Windows only allows administrators to create symbolic links unless Developer Mode is turned on. That single restriction is the entire reason nvm shells out to elevate.cmd.

Windows has a second kind of directory link, the junction. A junction can only point at a local directory — which is exactly and only what we need here — and creating one requires nothing beyond write access to the parent folder. No admin, no Developer Mode.

So nvmv use 20 deletes the link and recreates it as a junction pointing at %NVM_HOME%\v20.20.0. Because PATH still names the same link, every shell picks up the new Node immediately. Nothing else changes.

The five commands that touch that link — use, on, off, and uninstall or reinstall when the version happens to be the active one — are exactly the five nvmv reimplements. Everything else nvm does is downloads and text files under %NVM_HOME%, which you already own.

Keeping settings.txt honest

nvm on does not remember which version was active; it relinks to whatever version: says in %NVM_HOME%\settings.txt, a key nvm use writes. A tool that repoints the link without updating that key leaves a trap: the next off/on round trip silently reverts you to whichever version nvm last selected, possibly months ago. nvmv writes the key on every switch, clears it when you uninstall the active version, and nvmv doctor flags the mismatch if anything else drifts.

Requirements

  • Windows PowerShell 5.1 (ships with Windows) or newer.
  • nvm-for-windows already installed, with at least one Node version installed through it.
  • The folder containing the link must be writable by you. If nvm put its symlink at C:\nvm4w\nodejs, you are fine. If it put it under C:\Program Files\nodejs, see Troubleshooting.

Install

Unzip somewhere, open PowerShell in that folder, and run:

powershell -ExecutionPolicy Bypass -File .\install.ps1

That copies three scripts to %LOCALAPPDATA%\nvmv and appends that folder to your user PATH. Nothing is written to machine-wide settings, and the old PATH is saved to %LOCALAPPDATA%\nvmv\user-path-backup.txt first.

Then open a new terminal and run nvmv. The new terminal matters: the PATH entry is new, so existing shells will not find the command yet.

Options:

.\install.ps1 -InstallDir 'C:\tools\nvmv'   # put it somewhere else
.\install.ps1 -NoPath                       # copy the scripts, leave PATH alone

Everyday use

Check what you have:

> nvmv

  Installed Node versions

    v24.13.0
    v22.23.1
  * v20.20.0   (active)
    v20.16.0

  Link: C:\nvm4w\nodejs

Switch:

> nvmv use 20

  Now using v20.20.0 (ABI 115)
  Restart any running dev server or terminal task to pick it up.

.nvmrc

If a repo has a .nvmrc file containing, say, 20, then a bare nvmv use inside that repo reads it and switches for you. It searches parent folders too, so it works from any subdirectory:

> cd myrepo\src
> nvmv use
Using 20 from .nvmrc

  Now using v20.20.0 (ABI 115)

Pin the major version (20), not the exact patch. Native modules break across major versions, not patch versions, so that is the level that matters.

latest, lts, newest

newest is purely local: the highest version you have installed. latest and lts ask nodejs.org/dist/index.json (or your configured node_mirror) which release is current, then pick the matching installed version — so nvmv use lts lands on the newest install that is genuinely on an LTS line, rather than guessing from the version number. If the machine is offline, nvmv says so and falls back to reading the major version, since even-numbered majors are the LTS lines.

If the release it resolves to is not installed, nvmv tells you and stops:

> nvmv use latest

  No installed version matches 'latest'.
  Install it first with:  nvm install latest

Turning version management off

nvmv off removes the link, so nothing resolves through %NVM_SYMLINK% and node leaves your PATH. nvmv on puts it back, pointing at the version that was active when you turned it off:

> nvmv off
  Version management off. Nothing resolves through C:\nvm4w\nodejs now.

> nvmv on
  Version management on. Now using v24.13.0

Removing versions

nvmv uninstall works on any version, including the one you are using — that is the case nvm needs admin for, because it has to take the link down first. It demands an exact version rather than a prefix, so nvmv uninstall 20 is refused and cannot quietly delete whichever 20.x sorted first.

If the version was the active one, you are left with no Node until you pick another. nvmv says so rather than silently choosing for you. Should the folder turn out to be locked by a running process, nvmv puts the link back before it reports the failure, so a failed uninstall never strands you without a node.

What updates, and when

Once you switch, node and npm resolve to the new version in every terminal, including ones already open. The PATH entry never changed — only what the link points at — and Windows resolves that at the moment you launch a program.

Already-running processes keep the old Node. A nest start --watch, a tsc --watch, a pm2 daemon, or a running dev server all hold onto the node.exe they started with. Restart them.

Installing new versions

Downloading a version never needed admin, so nvmv just forwards it:

nvmv install 18.20.4
nvmv use 18

nvmv reinstall 18.20.4 does both, after deleting whatever is already there.

Using nvmv as nvm

Since unhandled commands are forwarded verbatim, complete with nvm's own exit codes, an alias makes the switch invisible. In your PowerShell profile:

Set-Alias nvm nvmv

nvmv resolves nvm.exe by its absolute path under %NVM_HOME%, so the alias cannot make it call itself.

Exit codes

0 on success, 1 when the requested version is not installed or a version you asked to remove is not there. That makes it safe in an npm pre* hook or a CI script if you want a build to fail fast on the wrong Node.

Forwarded commands return whatever nvm.exe returns. Note that nvm exits 0 even for a command it does not recognise, so nvmv frobnicate is a silent no-op — same as nvm frobnicate.

Troubleshooting

Start with:

nvmv doctor

"is NOT writable by you" — nvm installed its symlink somewhere you do not own, almost always C:\Program Files\nodejs. nvmv replaces the link inside that folder, so the global switch cannot work. Two ways out:

  1. Reinstall nvm-for-windows and, when it asks where to put the symlink, give it a path you own such as C:\nvm4w\nodejs. One-time, needs admin once, and nvmv works from then on.

  2. Use the per-shell fallback, which never touches the link at all. It prepends the version's folder to PATH for the current terminal only:

    . nvmv-here.ps1 20

    The leading dot is required — that is PowerShell's "dot-source" operator, which runs the script in your session instead of a throwaway child scope. Without it, the PATH change would vanish the instant the script ended.

"is a real directory, not a link" — something replaced the link with an actual Node install. nvmv refuses to delete it rather than destroy Node. Move that folder aside, then run nvmv on once to recreate the link.

"Could not remove the link" — a shell, editor, or running Node process has the folder open. Close them and retry.

"handled by nvm, but nvm.exe was not found" — you asked for a forwarded command such as nvmv install, and nvm is not on this machine. nvmv doctor prints where it looked. The commands nvmv implements itself keep working.

nvmv is not recognized — you are in a terminal that was open before the install. Open a new one. In VS Code, restart VS Code itself, since its integrated terminal inherits the environment VS Code was launched with.

An old nvmv runs instead of the new one — you have more than one copy and PATH is finding the wrong first. where nvmv lists them in the order Windows searches. Re-run install.ps1 -InstallDir <the one on PATH> to update in place.

Calling nvmv.ps1 directly swallows -v and -h — PowerShell binds a leading dash as a parameter name before the script sees it, and -v even prefix-matches the built-in -Verbose. The nvmv.cmd wrapper translates the flag forms before PowerShell can, so nvmv -v works; powershell -File nvmv.ps1 -v does not. Call nvmv, not the .ps1.

Uninstall

powershell -ExecutionPolicy Bypass -File .\uninstall.ps1

Takes the folder off your user PATH and deletes it. nvm, your Node versions, and whichever version is currently active are all left alone.

What gets touched

Thing Change
%LOCALAPPDATA%\nvmv created, holds three scripts
User PATH (HKCU\Environment) one entry appended; backed up first
%NVM_SYMLINK% repointed on each nvmv use, same as nvm use would
%NVM_HOME%\settings.txt the version: key is kept in step with the link
Machine-wide settings none
Your Node installs only what you ask uninstall / reinstall to remove

About

A drop-in replacement for nvm use on Windows that needs no elevation. Uses a directory junction instead of a symlink, so no UAC prompt and no Developer Mode.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors