Whether you’re a full-stack, backend, or frontend JavaScript developer, there will likely come a time when the projects on your system will require different versions of Node.js to function properly. Unless you’re running projects in a sandboxed environment (such as a VM), a system-wide Node installation is going to cause you issues because the version installed may be incompatible with some of your projects.
I’ve been using Node Version Manager to switch between multiple Node versions on my system for quite some time, and so far it has worked out great for me on macOS (and Linux1).
This post will walk you through installing nvm (on macOS), usage, and how to make sure each nvm instance’s npm version is up-to-date.
Installing nvm
If you’re on macOS, you’ll first want to install Homebrew and install nvm
with the following command:
brew install nvm
Afterwards, you’ll want to verify some lines were added to your .zshrc
(or .bashrc
) file located at $HOME/.zshrc
. If you don’t see them, be sure to add them (the last line is optional):
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh" # This loads nvm
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion
Restart any open terminals (or run source ~/.zshrc
) and nvm
will be ready to use. You can verify with the following command (you should see a version number printed, not an error):
nvm --version
If you’re on Linux or Windows, see the official installation instructions.
Setting the system default
To install a specific Node version, run the following in a Terminal, replacing the number with the version you want to use:
nvm install 20.10.0
To set it as the default version on your system:
nvm alias default 20.10.0
nvm use default
In your current session, and when you launch new Terminal sessions, the node
command will now use the version you set as default2.
NPM and global packages
Whenever you install a new version of Node with nvm
, it’s a good idea to make sure you also have the latest Node Package Manager (npm
) installed as well. Normally you would use npm
to upgrade itself, but for an nvm
install you need to run the following command instead:
nvm install --latest-npm
Next you’ll need to install any global packages you want available. For example, to install yarn
globally:
npm install --global yarn
Since every new version installed with nvm
is a clean install, you’ll need to re-install any global packages you want for that specific version of Node.
Per-project versions
Being able to use separate versions of Node for different projects on your system is the primary benefit of nvm
, and this can be configured by saving an .nvmrc
file at the root3 of your project with the Node version number:
18.16.1
In your Terminal (make sure the current directory is your project’s), run:
nvm install
nvm use
This will pick up the .nvmrc
file at the current working directory and install the version specified there. Next time, you’ll only need to run nvm use
to switch to the correct Node version. Note that when you switch to a different version (without the default
command), only that current Terminal session is affected. So if you have two tabs (or windows) open and you only ran nvm use
in one of them, the other tab will still have the default Node version in its PATH
.
Default same as project
What if the current project you’re working on uses the same version as the default on your system? In this case you don’t need to run either of the above commands since your session will already be using the correct Node version. I still recommend adding an .nvmrc
to your project in case you want to upgrade or change the default Node version on your system without affecting your project.
It’s also a good idea to check the .nvmrc
file into source control (ie. git
) so that others working on the same project are on the same version of Node as everyone else. Even if it’s a solo project, your future self will thank you for specifying the Node version if it’s been a while.
I spent a large amount of 2023 daily-driving Linux (EndeavourOS + KDE) and have since switched back to using macOS full-time, but that’s a topic for another time. ↩︎
This is what the commands you added to
.zshrc
do whenever you start a new Terminal session. ↩︎The top-level folder of your project ↩︎