Using nvm on Windows

November 26th 2021 Node.js PowerShell

I have been working on older Ionic Angular projects lately that can not be built with the latest version of Node.js. At first, it seemed like downgrading npm would suffice. When I realized that I would also need to downgrade my Node.js installation, I decided to bite the bullet and install NVM for Windows.

Since I already had Node.js installed on my machine, it seemed like a good idea to do a full uninstall first. I followed a great guide I found on Stack Overflow. In my case, it boiled down to this:

  • Clearing the npm cache by calling npm cache clean --force
  • Uninstalling Node.js from the Windows Programs & Features window
  • Deleting the npm and npm-cache folders from the %appdata% folder

When I was done with that, I downloaded nvm-setup.zip from the NVM for Windows releases page and ran the installer from that archive. After I restarted the terminal window, the nvm command was available to me.

I then installed all the Node.js versions that I might need to use in the near future:

nvm install 10.24.1
nvm install 12.22.7
nvm install 14.18.1
nvm install 16.13.0

It was time to switch to one of these versions and start working:

nvm use 10.24.1

Unfortunately, the call failed:

exit status 5: Access is denied.

This is because the tool uses symlinks that require admin privileges to create. The official recommendation is to use the tool from an admin terminal window.

I am not comfortable having admin privileges in my terminal, and I wanted to avoid having to open another terminal window when I want to switch to a different Node.js version. I decided to use the Start-Process PowerShell command as a workaround:

Start-Process -Verb RunAs nvm -Args "use 10.24.1"

It's basically sudo for Windows. The syntax is a bit complicated, so I created a few functions in my PowerShell profile to make the command easier to use:

Function Nvm-Use10
{
    Start-Process -Verb RunAs nvm -Args "use 10.24.1"
}

Function Nvm-Use12
{
    Start-Process -Verb RunAs nvm -Args "use 12.22.7"
}

Function Nvm-Use14
{
    Start-Process -Verb RunAs nvm -Args "use 14.18.1"
}

Function Nvm-Use16
{
    Start-Process -Verb RunAs nvm -Args "use 16.13.0"
}

Now I can just call one of those functions to switch to a different Node.js version:

Nvm-Use10

There was one last thing that was bugging me. The Linux/macOS version of nvm supports a .nvmrc file in the root folder of a project to specify the version you need. Then you can switch to the correct version simply by calling:

nvm use

Unfortunately, this is not supported by NVM for Windows. Since the projects I work on only use the nvm/* syntax, I created the following helper function to parse the contents of the .nvmrc file and switch to the correct version of Node.js:

Function Nvm-UseFromNvmrc
{
    $version = Get-Content .\.nvmrc -Raw
    Switch ($version.Trim().ToLower())
    {
        "lts/dubnium" { Nvm-Use10 }
        "lts/erbium"  { Nvm-Use12 }
        "lts/fermium" { Nvm-Use14 }
        "lts/gallium" { Nvm-Use16 }
    }
}

It's far from perfect, but it works well enough for me and required minimal effort to make it work. I can always improve it later if needed.

NVM for Windows is not a perfect solution, but it works well enough to make it easier to work with different versions of Node.js on Windows. To make it even easier to use, I added a few helper functions to my PowerShell profile.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License