Hey there!
As a fellow developer, I know how frustrating it can be to deal with multiple Node.js versions. One day a project runs fine, but the next it breaks mysteriously!
The culprit? Unexpected changes in Node versions.
Thankfully, you can take control and stop worrying by using the Node Version Manager (NVM).
In this hands-on guide, I‘ll share:
- Why juggling Node.js versions is a headache
- How NVM makes your life infinitely easier
- Step-by-step installation instructions for Windows and MacOS
- Tips from my experience for using NVM effectively
- The best practices I‘ve learned for version management
I‘ll also discuss some nerdy details around Node releases, convention conflicts, and NVM under the hood.
So bookmark this page and let‘s get started exploring NVM!
Why Managing Node.js Versions is a Pain
Before we dive into NVM, let‘s look at what makes Node version management complex.
As you know, new Node versions come out frequently – a major release every 6 months! With each release, there are upgrades and changes:
- New ES6 features get added
- APIs and modules work differently
- Bugs get fixed, others get introduced
This means your app may run fine on Node v6. But after upgrading to v8, errors may suddenly appear!
Some key reasons this happens:
1. Breaking changes
New releases can completely change or remove old Node APIs and features your app depends on.
For example, v7 removed the crypto timingSafeEqual() method. So apps using it would crash!
2. Unsupported syntax
Your app may use newer ES6 syntax not yet supported in the Node version you upgraded to.
Arrow functions, const/let, rest parameters, etc. often cause issues.
3. Deprecated functionality
Behaviour for deprecated features will change when you upgrade Node.
For instance, supporting the root command line option was removed in v15.
4. Compiler and dependency changes
The V8 JavaScript engine keeps evolving. NPM dependencies get updated too.
Apps compiled on older versions may not work right with newer Node releases.
5. Ecosystem fragmentation
Packages specify support for limited Node.js semver ranges. If you upgrade out of range, there could be incompatibilities.
Modules following outdated conventions can also behave unexpectedly.
These changes make smooth Node version upgrades impossible. You have to deal with regressions, rewrites, and refactors.
Of course, you can always pin your apps to a specific Node LTS version. But soon you‘ll miss out on cutting-edge features and performance improvements.
The ideal solution is to easily switch between multiple Node.js versions. That‘s exactly what NVM enables!
Why NVM is Your Node.js Version Management Saviour
NVM, short for Node Version Manager, is a simple command-line tool for managing multiple Node.js installations.
With NVM, you can:
- Install many Node.js versions side by side
- Switch between different versions easily
- Set a default Node version per project
This brings several key benefits:
No More Conflicts Between Node Versions
You can install and run any Node version needed for your apps without conflicts.
Old and new releases can co-exist peacefully. Your system paths stay clean too.
Use New JavaScript Features Quickly
Eager to try that hot new ES6 feature?
With NVM, you can quickly install newer Node versions and test drive the latest JavaScript goodies.
No need to mess with system-wide upgrades to do so.
Match Production Environments
Is your app behaving weirdly in production but runs fine locally?
The culprit is often mismatched Node versions.
NVM lets you install the exact same Node versions used in production. Now you can debug issues much faster.
Standardize Version Management
Your team can standardize on NVM for Node version management.
Set up a .nvmrc file per project listing the required version. Now anyone working on the project will get the right version automatically!
As you can see, NVM makes juggling multiple Node.js releases a breeze!
Ready to get started? Let‘s get NVM installed first.
Installing NVM on Windows
You‘ll be pleased to know NVM installs quickly and easily on Windows. Here‘s how:
Step 1: Download the Latest Installer
First, head to the nvm-windows GitHub Releases page.
This is where new versions are published.
Under Assets, grab the latest nvm-setup.zip file:

Take note of the version number you downloaded.
Step 2: Run the Installer Wizard
Unzip the installer and run nvm-setup.exe.
It will guide you through a few quick steps:
- Accept the license agreement
- Choose the installation location
- Set the Node symlink directory
The symlink is important – this is where the active Node binary will be accessible.
For example, C:\Program Files\Nodejs is a common symlink location.
Once everything looks good, click install. The process only takes a minute.
Step 3: Verify the Installation
To verify it completed successfully, open a new command prompt or PowerShell window.
Then check the version:
nvm --version
You should see the version number you downloaded before:

With that, NVM is installed and ready to use!
Time to get it set up on MacOS next.
Installing NVM on MacOS
MacOS installation is also pretty straightforward using the official script.
Here are the steps:
Step 1: Install Xcode Command Line Tools
NVM requires Xcode command line tools to compile and install Node versions.
Install them by running:
xcode-select --install
Follow the prompt to complete the installation. This will add the gcc and related tools needed.
Step 2: Download the NVM Install Script
Next, use curl in your Terminal to grab the install script:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
This will clone NVM into ~/.nvm, and add the required lines to your ~/.bash_profile or ~/.zshrc.
Step 3: Reload Your Shell Profile
For the changes to apply, reload your shell profile:
Bash:
source ~/.bash_profile
Zsh:
source ~/.zshrc
Step 4: Verify the Installation
Finally, check if NVM is available and its version:
nvm --version
Seeing the version is proof that NVM is installed correctly.
With NVM ready to go, let‘s look at how to use it.
Using NVM to Install and Manage Node.js
Now for the fun part – using NVM‘s many subcommands to install, switch between, and manage Node.js versions!
Installing Specific Node.js Versions
To install a version, use:
nvm install 14.17.6
For example:
nvm install 14.17.6
Downloading and installing node v14.17.6...
...
This will download the source code, compile it, and create a separate node_modules directory for v14.17.6.
You can confirm it completed via:
nvm ls
v14.17.6
To install the latest LTS, omit the version:
nvm install --lts
Switching Between Node Versions
After installing Node versions, you can switch between them using:
nvm use 14.17.6
This will point the node command to use v14.17.6 and its node_modules:
nvm use 14.17.6
Now using node v14.17.6
To go back to the system Node version:
nvm use system
Setting a Default Node Version
You can set a default Node version to use in any new shell:
nvm alias default 14.17.6
Now when you open a new terminal, node will automatically point to v14.17.6.
Automating Version Switching Per Project
Here is one of my favourite NVM features!
You can make NVM automatically switch Node versions when you enter a project folder.
Just create a .nvmrc file containing the Node version:
14.17.6
Now when you cd into this project, NVM detects .nvmrc and switches to using v14.17.6 automatically!
This way your team can standardize on the required Node version for a project.
Other Helpful Commands
Those are the most common commands I use.
But NVM has a lot more you can explore:
nvm current: Print currently activated versionnvm ls: List installed versionsnvm ls-remote: List all available remote versionsnvm uninstall: Remove an installed versionnvm reinstall-packages: Reinstall global NPM packages
Refer to the NVM documentation for all available options.
Now let‘s go over some tips and best practices.
Tips from My Experience for Using NVM Effectively
After using NVM extensively for my projects, here are some tips I‘ve found handy:
Install Global Packages Per Node Version
Remember each Node version has its own node_modules directory.
So you need to reinstall global NPM packages when switching between different versions:
nvm use 14.17.6
npm install -g gulp
Disable the System Node Version
To avoid accidentally using the wrong version, I recommend fully disabling the system Node.
Unset any symlink and rely solely on NVM‘s version switching.
Periodically Check for NVM Updates
The NVM developers are constantly shipping improvements and bug fixes.
So check the releases page every now and then for updates.
Understand How NVM Resolves Packages
NVM overrides Node‘s module resolution logic.
Packages present in a local node_modules folder will be used over global installs.
This can trip you up occasionally, so be aware of it.
Use Long-Term Support Versions for Production
For production apps, I suggest using the latest Node.js LTS version.
LTS releases are supported for 18+ months and ideal for stability.
Of course, always match the production environment locally via NVM!
NVM Best Practices for Team Workflows
When working in teams, you can standardize NVM usage for smooth collaboration:
-
Agree on an LTS version – Use the latest Node.js LTS as the default across projects.
-
Add a project-specific
.nvmrc– For any project needing a different Node version, add an.nvmrcfile at its root. -
Install matching versions in CI/CD – Your continuous integration pipelines should install the
.nvmrcversion too. -
Document NVM usage – Add a README note listing the supported Node.js versions for the project.
-
Stick to SemVer ranges for dependencies – Use flexible semantic versioning ranges like
~1.2.3for addons and packages.
This ensures anyone that clones a project gets the expected Node version and dependencies without hassles!
Understanding How NVM Works
Curious to know what NVM is doing behind the scenes? Let‘s lift up the hood!
The key to NVM is how it hooks into your shell‘s path lookup logic.
Path Lookup Order
Your shell searches various paths in order when you run commands.
For example, the lookup order may be:
- Local folder binaries (
./node) - User binaries (
~/.nvm/versions/node/v14.17.6/bin/node) - Global binaries (
/usr/local/bin/node) - System binaries (
/usr/bin/node)
NVM works by inserting a path like #2 with higher priority than #3 and #4.
So when you run node, it finds the NVM-managed version first.
Shim Files
NVM achieves this by using shim executables.
For example, it creates a node shim in ~/.nvm/versions/node/v14.17.6/bin/node.
This node shim acts as a proxy and passes execution to the actual node binary.
Shims allow NVM to intercept lookups and redirect them.
Environment Variables
NVM also leverages environment variables like PATH and _ to determine available versions.
For example, _ points to the Node executable of the currently activated version.
Check out this guide to learn more about how NVM hooks into shell paths.
The technical details may seem complex, but thankfully you don‘t need to know them for basic usage!
Now that you understand how NVM works, let‘s recap what we covered.
In Summary
Phew, that was a lot of information!
Let‘s quickly recap what you learned:
-
Why Node version management is hard – Conflicts, regressions, and ecosystem fragmentation make smooth upgrades impossible.
-
How NVM solves these problems – Allows side-by-side installs and switching between Node versions easily.
-
Installing NVM on Windows and MacOS – Downloading installers and running the setup guides.
-
NVM commands for Node.js version management – Installing, using, and automating version switching.
-
Tips and best practices – From disabling system Node to matching production environments.
-
How NVM hooks into shell paths – Using shims and environment variables.
Hopefully this guide has shown you how much easier NVM makes managing different Node.js versions.
No more tearing your hair out over version mismatches!
Let me know in the comments if you have any other questions.
Happy version managing!