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.
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.
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.
- 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 underC:\Program Files\nodejs, see Troubleshooting.
Unzip somewhere, open PowerShell in that folder, and run:
powershell -ExecutionPolicy Bypass -File .\install.ps1That 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 aloneCheck 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.
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.
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
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
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.
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.
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.
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 nvmvnvmv resolves nvm.exe by its absolute path under %NVM_HOME%, so the alias
cannot make it call itself.
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.
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:
-
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, andnvmvworks from then on. -
Use the per-shell fallback, which never touches the link at all. It prepends the version's folder to
PATHfor 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.
powershell -ExecutionPolicy Bypass -File .\uninstall.ps1Takes the folder off your user PATH and deletes it. nvm, your Node versions, and whichever version is currently active are all left alone.
| 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 |