Managing Multiple Node.js Versions with NVM: A Complete Guide
A practical walkthrough for developers who need to run different Node.js versions across projects, using Node Version Manager (nvm) to switch between versions seamlessly.
Published on 11 August, 2025
Categories:
Node.jsUnderstanding the Need for Multiple Node Versions
Modern JavaScript development often requires working with different Node.js versions simultaneously. You might maintain a legacy application running Node 14 while developing a new project on Node 20. Without proper version management, this becomes a nightmare of uninstalling and reinstalling Node.js repeatedly.
Node Version Manager (nvm) solves this problem by allowing you to install, manage, and switch between multiple Node.js versions on a single machine. Think of it as a version selector that keeps all your Node installations isolated and ready to use.
Installing NVM
Before installing nvm, remove any existing Node.js installations to avoid conflicts. This prevents PATH issues and ensures nvm has complete control over Node versions.
For macOS and Linux:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
Alternatively, use wget:
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
After installation, restart your terminal or run:
source ~/.bashrc
For zsh users:
source ~/.zshrc
For Windows:
Windows users need nvm-windows, a separate project. Download the installer from the official GitHub repository at github.com/coreybutler/nvm-windows/releases. Run the executable and follow the installation wizard.
Verify the installation:
nvm --version
Installing Node.js Versions
Once nvm is ready, installing Node versions becomes straightforward.
Install the latest LTS version:
nvm install --lts
Install a specific version:
nvm install 18.17.0
Install the latest release:
nvm install node
The keyword "node" always refers to the latest available version. When you install a version, nvm downloads the binaries and sets up the environment automatically.
View all available versions for installation:
nvm ls-remote
On Windows:
nvm list available
This command shows you every Node.js version ever released. The output can be lengthy, so pipe it to grep for filtering:
nvm ls-remote | grep "v18"
Switching Between Node Versions
The real power of nvm emerges when switching versions. Each project can use its required Node version without system-wide changes.
Switch to a specific version:
nvm use 16.14.0
Switch to the latest LTS:
nvm use --lts
Switch to the system-installed Node (if any):
nvm use system
When you run
nvm use, the current terminal session adopts that Node version. Open a new terminal, and you will need to set the version again unless you configure a default.Set a default Node version:
nvm alias default 18.17.0
Now every new terminal session starts with Node 18.17.0. This saves you from running
nvm use repeatedly.Essential NVM Commands
List installed versions:
nvm ls
This shows all Node versions on your machine with an arrow pointing to the currently active version:
v16.14.0
v18.17.0
-> v20.10.0
default -> 20.10.0 (-> v20.10.0)
Check the current version:
nvm current
Returns something like
v20.10.0.Uninstall a version:
nvm uninstall 16.14.0
Be careful here. Uninstalling removes the version completely, including all globally installed packages for that version.
Run a command with a specific Node version without switching:
nvm exec 18.17.0 node app.js
This executes
node app.js using Node 18.17.0 without changing your current version. Useful for one-off tasks.Check which version would be used:
nvm which 18.17.0
Returns the path to the Node binary for that version:
/Users/username/.nvm/versions/node/v18.17.0/bin/node
Project-Specific Version Management
Many developers use
.nvmrc files to lock Node versions per project. Create this file in your project root:echo "18.17.0" > .nvmrc
When you navigate to that directory, simply run:
nvm use
nvm reads the
.nvmrc file and switches to version 18.17.0 automatically. Team members cloning the repository can run the same command and get the correct version instantly.For automatic version switching when entering a directory, add this to your shell profile (
.bashrc or .zshrc):autoload -U add-zsh-hook load-nvmrc() { if [[ -f .nvmrc && -r .nvmrc ]]; then nvm use fi } add-zsh-hook chdir load-nvmrc
Now entering a directory with
.nvmrc triggers nvm use automatically.Managing Global Packages Across Versions
Global npm packages install separately for each Node version. When you install a tool like
nodemon globally on Node 18, it will not exist on Node 20.Install packages globally for the current version:
npm install -g nodemon
Migrate global packages when switching versions:
nvm install 20.10.0 --reinstall-packages-from=18.17.0
This installs Node 20.10.0 and copies all global packages from 18.17.0 to the new version. Saves time when upgrading between versions.
View global packages for current version:
npm list -g --depth=0
Troubleshooting Common Issues
Command not found after installation:
The shell cannot locate nvm. Check if the installation script added the initialization code to your profile file (
.bashrc, .zshrc, or .profile). Look for these lines:export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
If missing, add them manually and reload your shell.
Slow shell startup:
nvm initialization can slow down terminal startup. Use lazy loading by replacing the standard initialization with:
nvm() { unset -f nvm export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm "$@" }
This loads nvm only when you first use it.
Version not persisting across terminals:
Set a default version as shown earlier:
nvm alias default 18.17.0
Permission errors on Linux:
Never use sudo with nvm commands. This breaks the permission model. If you encounter permission issues, fix the nvm directory ownership:
sudo chown -R $USER:$USER ~/.nvm
Wrap Up
Node Version Manager transforms multi-version Node.js development from a headache into a simple workflow. Install what you need, switch when required, and maintain project-specific versions without breaking other projects. The
.nvmrc approach ensures team consistency, while the extensive command set handles edge cases cleanly.Master the core commands (install, use, ls, alias) and you will handle 95% of version management scenarios. Keep nvm updated occasionally by re-running the installation script, and remember that each Node version maintains its own global package ecosystem. This isolation prevents conflicts and keeps your development environment predictable.