How to manage Node versions without NVM

I've been using NVM for quite some time now, and I've always been happy with it. It's a great tool that makes it easy to install and switch between different versions of Node. However, I've recently started to feel that it's a bit too much for my needs. I don't need to switch between versions too often, and I don't need all the features that NVM provides. I just need a simple way to install and use different versions of Node. So I decided to try a different approach, and I'm happy to say that it's working great for me. In this article, I'm going to show you how to manage Node versions without NVM.

But why ditch NVM?

As I said, I only ever use 2-3 versions of Node at a time, and I don't need to switch between them too often. NVM is a great tool, but it has a lot of features that I don't need. And the added attraction layer often means that I can't control the finer details of how it works.

For example, just a few weeks ago I tried to install the current LTS version on a new machine. I ran the usual nvm install lts and expected a rather quick download and setup process. But it took a lot longer than I expected. A few minutes into the process I started wondering what was going on and realized that NVM was building Node from source, instead of downloading the pre-built binaries.

Why this was happening I have no idea, as I have a pretty typical setup, and precompiled binaries are readily available for my platform. But the fact that I couldn't control this behavior was a bit frustrating. I just wanted to install the pre-built binaries and be done with it. So I decided to look for an alternative.

So what's the alternative?

The workflow that I'm going to propose is not as easy as NVM, but it is extremely simple. It doesn't have any hidden behaviors or edge cases. It involves some manual work, but it's a great way to understand how Node version management works under the hood. And it's a great way to have a robust Node version management system without the need for any additional tools.

Let's take a closer look at what NVM does in a nutshell. It installs Node versions to your $HOME folder and manages the $PATH variable so that the node command in your terminal points to the version you currently need. That's it! This task can be accomplished with a few bash commands without the need for any additional tools.

The process step by step

  1. Let's create a folder for our Node versions. NVM creates a folder called ~/.nvm and I'm going to use ~/.node-versions for this purpose. You can use any folder you like, but I recommend using a hidden folder in your home directory to keep things clean.
mkdir ~/.node-versions
cd ~/.node-versions
  1. Now let's download the version of Node we need. You can find the download links on the official Node.js website. I'm going to use the current LTS version for this example.
wget https://nodejs.org/dist/v21.7.0/node-v21.7.0-darwin-arm64.tar.gz

Make sure to download the Binary version, not the installer or the source code. It's pretty much a ready-to-use version of Node that you can extract and run without any additional installation steps. The file you download should have a .tar.gz extension.

  1. Now let's extract the downloaded file to the folder we created in step 1.
tar -xzf node-v21.7.0-darwin-arm64.tar.gz v21.7.0

I'm naming the folder v21.7.0 to make it easier to understand which version of Node it contains. You can use any name you like, but I recommend using the version number to keep things clean.

  1. Now let's add the bin folder of the extracted Node version to our $PATH. You can do this by adding the following line to your ~/.zshrc or ~/.bashrc file.
export PATH="$HOME/.node-versions/v21.7.0/bin:$PATH"

Make sure to replace v21.7.0 with the name you used in step 3.

  1. Let's reload our shell to apply the changes we made to the $PATH.
source ~/.zshrc
  1. Now you can check if the version of Node you installed is available in your terminal.
node --version

If everything went well, you should see the version you installed.

Switching between versions

If you need to switch between versions, you can simply change the $PATH to point to the version you need. You can do this by changing the line you added to your ~/.zshrc or ~/.bashrc file in step 4.

Let's say you went through steps 1-4 to install version v14.17.0 and you want to switch to that version. You can simply change the line you added to your ~/.zshrc or ~/.bashrc file in step 4 to the following.

export PATH="$HOME/.node-versions/v14.17.0/bin:$PATH"
source ~/.zshrc
node --version

You should see the version you switched to.

Switching between versions with a single command

If you find yourself editing your ~/.zshrc or ~/.bashrc file way too often, you can use the alias command to create a shortcut for the versions that you use most often. For example, you can add the following lines to your ~/.zshrc or ~/.bashrc file to create shortcuts for the versions we installed in the previous steps.

alias node14='export PATH="$HOME/.node-versions/v14.17.0/bin:$PATH"'
alias node21='export PATH="$HOME/.node-versions/v21.7.0/bin:$PATH"'

$PATH works like a stack, so the version you added last will be the one used by the node command. So now you can then use the node14 and node21 commands to switch between versions.

node14

As always, you can verify that the version you switched to is available in your terminal.

node --version

Conclusion

I hope this guide was helpful to you. I know that it's not as easy as NVM, but it's a great way to understand how Node version management works under the hood. And it's a great way to have a robust Node version management system without the need for any additional tools. I'm using this myself now, and I'm happy to say that it's working great for me. I hope it works great for you too!