Install and Manage Node.js Versions with NVM

Okay, here’s a comprehensive article on installing and managing Node.js versions with NVM (Node Version Manager), aiming for around 5000 words. This will be a deep dive, covering everything from basic installation to advanced usage and troubleshooting.

Install and Manage Node.js Versions with NVM: A Comprehensive Guide

Node.js is a ubiquitous runtime environment for JavaScript, powering everything from web servers and APIs to desktop applications and command-line tools. One of the challenges of working with Node.js is managing different project dependencies. Different projects might require different, and sometimes incompatible, versions of Node.js. Manually managing these versions can quickly become a nightmare, leading to conflicts, broken builds, and wasted development time.

Enter NVM (Node Version Manager). NVM is a simple, yet incredibly powerful, POSIX-compliant bash script that allows you to install, manage, and switch between multiple Node.js versions with ease. It’s an essential tool for any serious Node.js developer, and this guide will provide a complete walkthrough of its installation, usage, and advanced features.

1. Why Use NVM?

Before diving into the installation process, let’s solidify why NVM is such a crucial tool:

  • Multiple Node.js Versions: The core benefit. You can have Node.js v12, v14, v16, v18, (and any other versions) installed simultaneously on your system without conflicts.
  • Project-Specific Versions: You can specify the exact Node.js version required for each project, ensuring consistency and avoiding compatibility issues. This is typically done using a .nvmrc file (discussed later).
  • Easy Switching: Switching between versions is a matter of a single command (nvm use <version>). This is dramatically faster and simpler than manual installation/uninstallation.
  • Isolation: Each Node.js version installed with NVM has its own set of global packages. This prevents global package conflicts between projects using different Node.js versions.
  • Simplified Updates: Updating to the latest patch version of a specific Node.js release line is straightforward (nvm install <version> --reinstall-packages-from=<version>).
  • No System-Wide Modifications (Usually): NVM typically manages Node.js versions within your user’s home directory, avoiding the need for root/administrator privileges for most operations (unlike system-wide installations). This is a major security and stability advantage.
  • Open Source and Actively Maintained: NVM is an open-source project with a large and active community, ensuring ongoing development, bug fixes, and support.

2. Installation

The installation process for NVM varies slightly depending on your operating system (Linux, macOS, or Windows). We’ll cover each platform in detail. Important Note: Before installing NVM, it’s highly recommended to remove any existing globally installed Node.js versions to avoid conflicts. This usually involves uninstalling through your system’s package manager (apt, yum, brew, etc.) or by manually removing the Node.js installation directories.

2.1. Linux and macOS (Using the Installation Script)

The recommended and easiest way to install NVM on Linux and macOS is to use the installation script. This script downloads NVM, installs it in your home directory, and configures your shell environment.

  1. Open a Terminal: Open your terminal or command-line interface.

  2. Download and Run the Script: Execute the following command. This command uses curl to download the installation script and then pipes it to bash for execution:

    bash
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

    OR, if you don’t have curl, use wget:
    bash
    wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

    Important Note: Replace v0.39.5 with the latest version number. Check the official NVM repository on GitHub (https://github.com/nvm-sh/nvm) for the most up-to-date version. It’s generally best practice to use the latest stable release. The installation script will:

    • Clone the NVM repository into ~/.nvm.
    • Add the necessary lines to your shell’s profile file (e.g., ~/.bashrc, ~/.zshrc, ~/.profile, or ~/.bash_profile) to source the nvm.sh script. This makes the nvm command available in your terminal.
  3. Restart Your Terminal (or Source the Profile): For the changes to take effect, you need to either close and reopen your terminal or manually source your profile file. For example, if you use Bash:

    bash
    source ~/.bashrc

    Or, if you use Zsh:

    bash
    source ~/.zshrc

  4. Verify Installation: To ensure NVM is installed correctly, run:

    bash
    command -v nvm

    This should output nvm, confirming successful installation. If it doesn’t, double-check the steps above, paying close attention to the profile file modifications. You can also try:

    bash
    nvm --version

    This should display the installed version of nvm.

2.2. Windows

NVM for Windows is a separate project (available at https://github.com/coreybutler/nvm-windows) and is not directly related to the POSIX-compliant NVM discussed above. However, it provides similar functionality for managing Node.js versions on Windows.

  1. Download the Installer: Go to the releases page of the nvm-windows repository on GitHub (https://github.com/coreybutler/nvm-windows/releases). Download the nvm-setup.zip file for the latest release.

  2. Extract and Run the Installer: Extract the contents of the ZIP file and run nvm-setup.exe. Follow the on-screen instructions. The installer will:

    • Install NVM to a directory of your choice (the default is usually C:\Users\<YourUsername>\AppData\Roaming\nvm).
    • Add the NVM directory to your system’s PATH environment variable. This makes the nvm command available in your command prompt or PowerShell.
  3. Restart Your Command Prompt/PowerShell: Close and reopen your command prompt or PowerShell window for the changes to take effect.

  4. Verify Installation: Open a command prompt or PowerShell and run:

    nvm version

    This should output the installed version of NVM for Windows.

2.3. Manual Installation (Linux/macOS – Advanced)

While the installation script is recommended, you can also install NVM manually. This gives you more control over the installation process but requires a bit more technical expertise.

  1. Clone the Repository:

    bash
    git clone https://github.com/nvm-sh/nvm.git ~/.nvm

  2. Create the NVM Directory (if it doesn’t exist):

    bash
    mkdir ~/.nvm

  3. Source the nvm.sh Script: Add the following lines to your shell’s profile file (e.g., ~/.bashrc, ~/.zshrc, ~/.profile, or ~/.bash_profile):

    bash
    export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
    [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion

    This code does the following:

    • export NVM_DIR=...: Sets the NVM_DIR environment variable, pointing to the NVM installation directory. It intelligently handles both standard home directories and XDG-compliant configurations.
    • [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh": Checks if the nvm.sh script exists and, if so, sources it (runs it in the current shell). This loads the NVM functions and makes the nvm command available.
    • [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion": Loads bash completion, enabling tab completion for nvm commands.
  4. Restart Your Terminal (or Source the Profile): As with the script installation, restart your terminal or source your profile file (e.g., source ~/.bashrc).

  5. Verify Installation: Use command -v nvm or nvm --version to verify.

3. Basic Usage: Installing, Switching, and Listing Node.js Versions

Now that NVM is installed, let’s explore its core functionality.

3.1. Installing Node.js Versions

The nvm install command is used to install specific Node.js versions.

  • Install a Specific Version:

    bash
    nvm install 18.17.1 # Installs version 18.17.1
    nvm install 16.13.0 # Installs version 16.13.0

  • Install the Latest LTS (Long-Term Support) Version:

    bash
    nvm install --lts # Installs the latest LTS release

    This is generally recommended for production environments due to its stability and extended support.

  • Install a specific LTS release by codename:

    bash
    nvm install --lts=gallium #install LTS release with codename 'gallium'

  • Install the Latest Stable Version:

    bash
    nvm install node # Installs the latest stable release (may be newer than LTS)

  • Install from .nvmrc (more on this later):

nvm install
If run without arguments, the nvm install command reads the .nvmrc file from the current directory (or a parent directory), and attempts to install that version.

During the installation process, NVM downloads the Node.js binary (or source code, if necessary) for your platform, compiles it (if needed), and places it in the ~/.nvm/versions/node directory (on Linux/macOS) or the NVM installation directory (on Windows). It also installs the corresponding version of npm (Node Package Manager).

3.2. Listing Installed Versions

To see which Node.js versions you have installed, use the nvm ls command:

bash
nvm ls

This will output a list of installed versions, with an arrow (->) indicating the currently active version. Example output:

v16.13.0
-> v18.17.1
system

  • v16.13.0: Version 16.13.0 is installed.
  • -> v18.17.1: Version 18.17.1 is installed and is the currently active version.
  • system: Refers to the system-installed Node.js (if any). NVM will prioritize its managed versions over the system version.

You can also list available versions to install:
nvm ls-remote

This command will list out a large list of available Node.js versions you can install, from very old to very new. You might want to filter it, for instance:

bash
nvm ls-remote | grep v18 # Show only versions starting with v18

3.3. Switching Between Versions

The nvm use command is used to switch between installed Node.js versions:

bash
nvm use 16.13.0 # Switch to version 16.13.0
nvm use 18.17.1 # Switch to version 18.17.1
nvm use node # Switch to the latest installed version
nvm use --lts # Switch to the latest installed LTS version

After running nvm use, the specified version becomes the active version for your current shell session. This means that when you run node or npm, you’ll be using the binaries from that specific version. The change is not permanent across sessions; when you open a new terminal, it will revert to the default version (which you can set, as described later).

3.4. Setting a Default Version

To set a default Node.js version that will be used in new terminal sessions, use the nvm alias default command:

bash
nvm alias default 18.17.1 # Set version 18.17.1 as the default

Now, whenever you open a new terminal, version 18.17.1 will be automatically activated.

3.5. Uninstalling Node.js Versions

To remove an installed Node.js version, use the nvm uninstall command:

bash
nvm uninstall 16.13.0 # Uninstall version 16.13.0

This will remove the corresponding directory and binaries from NVM’s managed versions.

4. Project-Specific Node.js Versions with .nvmrc

One of NVM’s most powerful features is the ability to specify a Node.js version on a per-project basis using a .nvmrc file. This ensures that everyone working on a project uses the same Node.js version, preventing compatibility issues and making collaboration smoother.

4.1. Creating a .nvmrc File

In the root directory of your project, create a file named .nvmrc (no file extension). This file should contain a single line specifying the desired Node.js version. For example:

18.17.1

Or, you can specify an LTS release:

lts/hydrogen
Or even just:
lts/*

Or the latest stable:
node

4.2. Using nvm use with .nvmrc

Once you have a .nvmrc file in your project, you can simply run nvm use (without any arguments) within the project directory:

bash
cd my-project
nvm use

NVM will automatically read the .nvmrc file and switch to the specified version. If the version is not installed, NVM will prompt you to install it.

4.3. Using nvm install with .nvmrc

If the version specified in the .nvmrc file is not installed, you can use nvm install (without any arguments) within the project directory:

bash
cd my-project
nvm install

NVM will read the .nvmrc and install the specified version.

4.4. Automatic Version Switching (with Shell Integration)

For even greater convenience, you can configure your shell to automatically switch to the Node.js version specified in a .nvmrc file whenever you cd into a project directory. This requires adding some code to your shell’s profile file (e.g., ~/.bashrc, ~/.zshrc).

The NVM documentation provides recommended functions for this. Here’s an example for Bash (add this to your ~/.bashrc):

“`bash

Place this after the NVM sourcing in your .bashrc

autoload -U add-zsh-hook
load-nvmrc() {
local nvmrc_path=”$(nvm_find_nvmrc)”

if [ -n “$nvmrc_path” ]; then
local nvmrc_node_version=$(nvm version “$(cat “${nvmrc_path}”)”)

if [ "$nvmrc_node_version" = "N/A" ]; then
  nvm install
elif [ "$nvmrc_node_version" != "$(nvm current)" ]; then
  nvm use
fi

elif [ -n “$(PWD=$OLDPWD nvm_find_nvmrc)” ] && [ “$(PWD=$OLDPWD nvm current)” != “$(nvm version “$(cat “$(PWD=$OLDPWD nvm_find_nvmrc)”)”)” ]; then
echo “Found ‘$OLDPWD/.nvmrc’ with Node version <$(cat “$(PWD=$OLDPWD nvm_find_nvmrc)”)>”
nvm use
fi
}

add-zsh-hook chpwd load-nvmrc
load-nvmrc
And this for Zsh (add this to your `~/.zshrc`):bash

Place this after the NVM sourcing in your .zshrc

autoload -U add-zsh-hook
load-nvmrc() {
local nvmrc_path=”$(nvm_find_nvmrc)”

if [ -n “$nvmrc_path” ]; then
local nvmrc_node_version=$(nvm version “$(cat “${nvmrc_path}”)”)

if [ "$nvmrc_node_version" = "N/A" ]; then
  nvm install
elif [ "$nvmrc_node_version" != "$(nvm current)" ]; then
  nvm use
fi

elif [ -n “$(PWD=$OLDPWD nvm_find_nvmrc)” ] && [ “$(PWD=$OLDPWD nvm current)” != “$(nvm version “$(cat “$(PWD=$OLDPWD nvm_find_nvmrc)”)”)” ]; then
echo “Found ‘$OLDPWD/.nvmrc’ with Node version <$(cat “$(PWD=$OLDPWD nvm_find_nvmrc)”)>”
nvm use
fi
}

add-zsh-hook chpwd load-nvmrc
load-nvmrc
“`

This code defines a function (load-nvmrc) that is executed whenever you change directories (chpwd). The function does the following:

  1. Finds the .nvmrc File: It uses the nvm_find_nvmrc function (provided by NVM) to locate the nearest .nvmrc file in the current directory or any parent directory.
  2. Checks the Version: It reads the Node.js version specified in the .nvmrc file.
  3. Installs or Switches:
    • If the specified version is not installed (N/A), it runs nvm install to install it.
    • If the specified version is different from the currently active version, it runs nvm use to switch to the correct version.

With this setup, you can seamlessly move between projects with different Node.js version requirements, and NVM will handle the switching automatically. Remember to source your profile after making changes: source ~/.bashrc or source ~/.zshrc.

5. Advanced Usage and Tips

Let’s delve into some more advanced NVM features and useful tips.

5.1. Reinstalling Global Packages

When you install a new Node.js version, it comes with its own clean set of global packages. If you want to copy global packages from a previous version, you can use the --reinstall-packages-from flag:

bash
nvm install 18.17.1 --reinstall-packages-from=16.13.0

This will install version 18.17.1 and then attempt to reinstall all global packages that were installed in version 16.13.0. Note that this might not always work perfectly, especially if packages have native dependencies that are incompatible between Node.js versions. It’s a good starting point, but you might need to manually reinstall some packages.

5.2. Using Specific npm Versions

NVM primarily manages Node.js versions, but each Node.js version comes bundled with a specific version of npm. While you usually don’t need to manage npm versions directly, it’s possible.

NVM doesn’t directly manage npm versions. If you need a specific npm version, you typically install it globally within a specific Node.js version:

bash
nvm use 18.17.1 # Switch to the desired Node.js version
npm install -g [email protected] # Install a specific npm version globally (for this Node.js version)

This installs npm version 8.19.2 globally, but only within the context of Node.js version 18.17.1. When you switch to a different Node.js version, you’ll have the npm version bundled with that Node.js version.

5.3. Running Commands with Specific Node.js Versions (nvm exec)

The nvm exec command allows you to run a command using a specific Node.js version without permanently switching your shell’s active version.

bash
nvm exec 16.13.0 node -v # Run `node -v` using version 16.13.0
nvm exec 18.17.1 npm run build # Run `npm run build` using version 18.17.1

This is useful for one-off tasks or for testing your code with different Node.js versions without modifying your shell’s environment.

5.4. Listing Remote Versions (with Filtering)

As we saw earlier, nvm ls-remote lists all available Node.js versions. You can filter this list using grep:

bash
nvm ls-remote | grep v18 # Show only versions starting with v18
nvm ls-remote | grep -E 'v16\.(1[3-9]|1[4-9]\.[0-9]+)' # Show v16 versions >= 16.13.0

The -E flag enables extended regular expressions, allowing for more complex filtering.

5.5. Deactivating NVM (Temporarily)

If you need to temporarily disable NVM for your current shell session, you can use:

bash
nvm deactivate

This will remove the NVM-related modifications from your shell’s environment. To re-enable NVM, you’ll need to source your profile file again (e.g., source ~/.bashrc).

5.6. NVM and Shell Aliases

Be cautious when using shell aliases in conjunction with NVM, especially within scripts. Aliases are expanded by the shell before NVM has a chance to modify the environment. This can lead to unexpected behavior. It’s generally better to use nvm exec or explicitly specify the full path to the Node.js binary within your scripts.

5.7. Caching Downloads
NVM caches downloaded Node.js binaries. This speeds up subsequent installations of the same version. The cache location is typically within the NVM directory (e.g., ~/.nvm). You usually don’t need to interact with the cache directly, but it’s good to know it exists.

5.8 Using nvm which

The nvm which command shows the full path to the Node.js executable for a given version:

bash
nvm which 18.17.1

This can be useful for debugging or for configuring external tools that need to know the exact location of the Node.js binary.

5.9 Using nvm run
The command nvm run allows you to execute node scripts using the node version specified.
nvm run 16.3.1 app.js #Runs app.js with node version 16.3.1

5.10 Using nvm current
Displays the current active node version managed by nvm.
nvm current

6. Troubleshooting

Here are some common issues and solutions when working with NVM:

  • nvm: command not found:
    • Cause: NVM is not installed correctly, or the necessary lines haven’t been added to your shell’s profile file.
    • Solution: Double-check the installation steps, ensuring you’ve sourced your profile file (e.g., source ~/.bashrc) or restarted your terminal. Verify that the NVM_DIR environment variable is set correctly.
  • nvm use doesn’t seem to work:
    • Cause: You might be in a subshell, or there might be conflicts with shell aliases or functions.
    • Solution: Try running nvm deactivate and then nvm use <version>. Check your shell’s profile file for any conflicting aliases or functions. Ensure you’re using the correct profile file for your shell (e.g., ~/.bashrc for Bash, ~/.zshrc for Zsh).
  • Installation fails with permission errors:
    • Cause: You might be trying to install NVM in a directory where you don’t have write permissions.
    • Solution: Ensure you’re installing NVM in your home directory (~/.nvm is the default). Avoid using sudo with NVM unless absolutely necessary (and you understand the implications).
  • Global packages are not working after switching versions:
    • Cause: Each Node.js version has its own set of global packages.
    • Solution: You need to reinstall the global packages for the new Node.js version. Use npm install -g <package-name> within the context of the desired Node.js version (after using nvm use). Consider using the --reinstall-packages-from flag when installing a new version.
  • .nvmrc file is not being respected:
    • Cause: You might not have the automatic version switching functionality configured in your shell, or there might be an error in your .nvmrc file.
    • Solution: Make sure you’ve added the necessary code to your shell’s profile file (as described in Section 4.4). Verify that the .nvmrc file contains a valid Node.js version string. Try running nvm use manually within the project directory to see if it works.
  • Slow installation:
    • Cause: NVM downloads Node.js binaries (or source code) from the internet. A slow internet connection can cause slow installations.
    • Solution: There is not much you can do about a slow internet connection. Try to install when network traffic might be lower. If it consistently fails, verify your network configuration.
  • NVM windows not recognizing installed Node version
    • Cause: Could be an issue with symlinks or environment variables.
    • Solution: Try nvm use <version> even if nvm list shows it as active. If that doesn’t work, check your system’s PATH environment variable to ensure the correct NVM directory and the directory for the specific Node.js version are included and in the correct order (NVM’s path should come before any system-wide Node.js paths). As a last resort, reinstall NVM for Windows.
  • Compatibility Issues
  • Cause: Very rarely, NVM itself might have a bug or compatibility issue with a very new or very old Node.js version.
  • Solution: Check the NVM GitHub repository for issues or discussions related to the specific Node.js version you’re having trouble with. Consider trying a slightly different NVM version or Node.js version.
  • Permission Denied on nvm.sh
    • Cause: The nvm.sh file might not have execute permissions.
    • Solution: Run chmod +x ~/.nvm/nvm.sh (or the appropriate path to nvm.sh) to give it execute permissions.
  • npm command not found after installing a new version:
  • Cause: It is rare, but the installation might have not completed.
  • Solution: Run nvm install <version> again, and ensure there are no errors.

7. Alternatives to NVM

While NVM is the most popular Node.js version manager, there are a few alternatives:

  • n: Another popular Node.js version manager, similar to NVM. It’s also a shell script and provides a simple interface for managing Node.js versions. https://github.com/tj/n
  • asdf: A more general-purpose version manager that can handle multiple languages and tools, including Node.js, Python, Ruby, and more. https://asdf-vm.com/
  • fnm: Fast Node Manager, written in Rust, designed for speed. https://github.com/Schniz/fnm
  • Volta: A JavaScript Tool Manager, also written in Rust. It manages Node.js versions and also handles package manager versions (npm, yarn). https://volta.sh/

The choice of version manager often comes down to personal preference and project requirements. NVM remains a strong choice due to its simplicity, widespread adoption, and active community.

8. Conclusion

NVM is an indispensable tool for Node.js developers. Its ability to manage multiple Node.js versions, simplify switching between them, and provide project-specific configurations makes it essential for maintaining a clean and efficient development environment. By following the instructions in this guide, you can confidently install, configure, and use NVM to streamline your Node.js workflow. Remember to consult the official NVM documentation for the most up-to-date information and to explore the various advanced features that can further enhance your development experience. Mastering NVM will save you significant time and frustration, allowing you to focus on building great software instead of wrestling with Node.js version conflicts.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top