How to Install Node.js and npm on Ubuntu and Other Linux Distributions

How to Install Node.js and npm on Ubuntu and Other Linux Distributions

Reading time1 min
#Node.js#npm#Ubuntu#Linux#NodeSource#nvm

How to Install Node.js and npm on Ubuntu and Other Linux Distributions

npm ships with Node.js, so "install npm" and "install Node" are the same task. The only exception is Debian and Ubuntu's own packages, where npm is a separate package.

Pick a version first. Production should run an LTS release. As of early October 2026, Node.js 24 is the active LTS, 22 is in maintenance, and 26 is the current release about to become LTS. The release table at nodejs.org shows the status at any time.

There are three reasonable ways to install it:

MethodVersionScopeGood for
Distribution packagesWhatever the release ships, often oldSystem-wideQuick installs where the version does not matter
NodeSource repositoryAny supported majorSystem-wide, updated by apt/dnfServers, CI images
nvmAny version, several side by sidePer userDevelopment machines

Pick one per machine. Mixing them leaves several node binaries in PATH and confusing results. Check what is there now:

which -a node npm
node -v

Option 1: distribution packages

sudo apt update
sudo apt install nodejs npm
node -v

Ubuntu and Debian freeze the Node.js version for the life of the release, so an LTS that is a couple of years old usually has an old Node.

On Fedora, sudo dnf install nodejs npm gets a recent version. On RHEL 8 and 9, dnf module list nodejs shows the available streams. On RHEL 9, for example, sudo dnf module install nodejs:22 installs Node.js 22.

Option 2: NodeSource repository

NodeSource publishes signed apt and dnf repositories per Node.js major version. Remove the distro packages first, because NodeSource's nodejs package already contains npm and conflicts with the separate npm package:

sudo apt remove nodejs npm

Then add the repository for the major you want and install:

curl -fsSL https://deb.nodesource.com/setup_24.x -o nodesource_setup.sh
less nodesource_setup.sh          # read it before running it as root
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejs
node -v && npm -v

The script adds the signing key to /usr/share/keyrings/nodesource.gpg and a source file at /etc/apt/sources.list.d/nodesource.sources. From then on sudo apt upgrade delivers patch releases for that major.

On Fedora, RHEL, Rocky, AlmaLinux and Amazon Linux 2023:

curl -fsSL https://rpm.nodesource.com/setup_24.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo dnf install -y nodejs

There is also setup_lts.x, which follows whatever the current LTS is. On servers, pin the major (setup_24.x) so a jump to the next major is a deliberate change. To move to a new major later, run the newer setup script and sudo apt install nodejs again.

Option 3: nvm

nvm (Node Version Manager) installs Node.js into your home directory and switches versions per shell or per project. No sudo involved.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
source ~/.bashrc
nvm install --lts
nvm alias default 'lts/*'
node -v

Check the nvm releases page for the latest tag before copying the URL. Useful commands:

nvm ls                  # installed versions
nvm install 22          # another major
nvm use 22              # switch in this shell
echo 24 > .nvmrc        # pin a version for a project
nvm use                 # reads .nvmrc

One limitation: nvm is a shell function loaded from ~/.bashrc. cron jobs, systemd services and sudo do not see it. For those, use the absolute path that nvm which 24 prints, or install Node system-wide with option 1 or 2.

Fix EACCES errors with global packages

With a system-wide Node, npm install -g tries to write under /usr/lib/node_modules or /usr/local/lib/node_modules and fails with EACCES: permission denied. Do not fix that with sudo npm install -g: package install scripts then run as root and you end up with root-owned files in your home directory. Point npm at a directory you own instead:

mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
npm install -g pnpm

nvm users do not need this, since everything already lives in ~/.nvm. For one-off tools, npx tool-name avoids global installs entirely.

Build tools for native modules

Some npm packages compile C++ code during installation through node-gyp, which needs a compiler, make and Python:

sudo apt install build-essential python3      # Ubuntu, Debian
sudo dnf install gcc-c++ make python3         # Fedora, RHEL

Verify

node -e 'console.log(process.version, process.arch)'
npm -v
npm config get prefix

Uninstall

# apt or NodeSource
sudo apt purge nodejs npm
sudo rm /etc/apt/sources.list.d/nodesource.sources /usr/share/keyrings/nodesource.gpg

# nvm: one version, or everything
nvm uninstall 22
rm -rf ~/.nvm    # then remove the nvm lines from ~/.bashrc

Quick reference

sudo apt install nodejs npm                                   # distro version
curl -fsSL https://deb.nodesource.com/setup_24.x -o ns.sh     # NodeSource, Node 24
sudo -E bash ns.sh && sudo apt install -y nodejs
curl -fsSL https://rpm.nodesource.com/setup_24.x -o ns.sh     # NodeSource on dnf systems
sudo bash ns.sh && sudo dnf install -y nodejs
nvm install --lts && nvm alias default 'lts/*'                # per-user with nvm
npm config set prefix ~/.npm-global                           # global installs without sudo
sudo apt install build-essential                              # native addons