Short answer: on Ubuntu or Debian, add the NodeSource repository and run sudo apt install nodejs. It installs the current LTS release with npm and npx. For several versions per user, use nvm: nvm install --lts. On Windows and Windows Server, run the LTS .msi from nodejs.org. Then check with node -v and npm -v.
sudo apt update && sudo apt install -y ca-certificates curl
curl -fsSL https://deb.nodesource.com/setup_lts.x -o nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejs
node -v && npm -vPlain sudo apt install nodejs without NodeSource is the tempting shortcut, and on a new server it is the wrong one: Debian 12’s own package is Node.js 18 (18.20.4 in the bookworm package index), which is past its upstream end of life, and npm is a separate package there. The rest of this guide covers which version to pick, nvm, the official binaries, Windows Server, updating Node and npm, and keeping the app running.
Which Node.js version should I install?
Up to Node.js 26, a new major version has come out every six months. Even-numbered majors become LTS (Long Term Support) releases and get security fixes for about 30 months from their first release; odd-numbered majors are “Current” releases that never become LTS and are retired after about eight months. On a server, install an LTS line. The schedule as of October 2026, from the Node.js release schedule (nodejs.org and the nodejs/Release repository, which also announces any change to this rhythm):
| Line | Status | End of life |
|---|---|---|
| Node.js 26 | Current, scheduled to become LTS at the end of October 2026 | April 2029 |
| Node.js 24 (Krypton) | LTS, in its maintenance phase since October 2026 | 30 April 2028 |
| Node.js 22 (Jod) | LTS, maintenance phase | 30 April 2027 |
| Node.js 25 | Odd-numbered, never LTS | Ended June 2026 |
| Node.js 20 (Iron) | End of life | Ended 30 April 2026 |
| Node.js 18 and older | End of life | Ended April 2025 or earlier |
For a new install today that means Node.js 24, or 26 once it is LTS and your framework supports it. Dates move, so check rather than trust any article, this one included:
nvm ls-remote --lts | tail -n 3 # newest LTS releases (needs nvm, below)
node -p process.release.lts # LTS codename of the running node, or undefinedThe download page on nodejs.org labels the LTS build as well. The second command answers “is what I have an LTS release?”: it prints the codename (Krypton on Node.js 24, Jod on 22) and undefined on an odd-numbered Current line.
Which install method should I use?
| Method | Best for | Versions | Updates |
|---|---|---|---|
| NodeSource apt repository | Servers and services, every user | One major, system-wide | apt upgrade |
| nvm | Development, a single deploy user | Many side by side, per user | nvm install |
| Official binaries | Other distributions, fixed paths | Any, where you unpack it | By hand |
| MSI installer or winget | Windows and Windows Server | One, system-wide | Newer MSI or winget upgrade |
| Distribution package | Tools that accept an old Node.js | Whatever the release ships | apt upgrade, security fixes only |
Do not mix two of them on one machine without a reason: a shell, a cron job and a service can each end up with a different node, and that is where most “works in my terminal, fails in production” problems come from.
How do I install Node.js on Ubuntu or Debian?
Use NodeSource, which publishes Node.js as apt packages. One package, nodejs, contains node, npm and npx, installed into /usr/bin. Every user, sudo, cron and systemd look there, which is what you want for a server that runs a service. To stay on one major line instead of following whatever is the newest LTS, use that major’s script, and read it before running it as root:
curl -fsSL https://deb.nodesource.com/setup_24.x -o nodesource_setup.sh
less nodesource_setup.sh
sudo -E bash nodesource_setup.sh
sudo apt install -y nodejsThe script adds NodeSource’s signing key and an apt source for that major; from then on, apt upgrade brings new 24.x releases with the rest of the system. What the distributions themselves ship, for comparison:
| Release | apt install nodejs gives | npm |
|---|---|---|
| Debian 12 | Node.js 18 (18.20.4) | Separate npm package (9.2.0) |
| Debian 13 | Node.js 20 | Separate package |
| Ubuntu 22.04 | Node.js 12 | Separate package |
| Ubuntu 24.04 | Node.js 18 | Separate package |
| Ubuntu 26.04 | Node.js 22 | Separate package |
Only Ubuntu 26.04’s package is still an LTS line that gets upstream fixes. On Rocky Linux and AlmaLinux, AppStream carries current majors (as module streams on version 9); the npx guide lists the dnf commands.
How do I install Node.js with nvm?
nvm (Node Version Manager) installs Node.js into ~/.nvm, for your user only, with any number of versions side by side. It is the right tool on a development machine and for a deploy user who owns one app; it needs no root at all.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
# open a new terminal (or run: . ~/.nvm/nvm.sh), then:
nvm install --lts # newest LTS; the first version you install becomes the default
nvm install 22 # another major next to it
nvm use 22 # switch this shell only
nvm alias default 24 # what every new shell starts withThe URL above carries the nvm release that was current on 12 October 2026; the README in the nvm-sh/nvm repository names the newest. A project can pin its version in a file: echo 24 > .nvmrc, after which nvm use in that directory picks it up. If the new terminal answers nvm: command not found, the installer wrote its lines to a file your shell does not read: nvm: command not found has the fix for bash, zsh and SSH logins.
How do I install the official Node.js binaries?
nodejs.org publishes prebuilt archives for Linux on x64 and arm64. They suit a distribution NodeSource does not cover, a server without third-party apt sources, or a fixed install path. Pick the file from the checksum list so no version number needs typing, and verify it before unpacking:
ARCH=x64
curl -fsSLO https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt
FILE=$(grep -o "node-v[0-9.]*-linux-$ARCH.tar.xz" SHASUMS256.txt)
curl -fsSLO "https://nodejs.org/dist/latest-v24.x/$FILE"
grep "$FILE" SHASUMS256.txt | sha256sum -c -
sudo mkdir -p /opt/node
sudo tar -xJf "$FILE" -C /opt/node --strip-components=1
sudo ln -sf /opt/node/bin/node /opt/node/bin/npm /opt/node/bin/npx /usr/local/bin/
node -vsha256sum -c must print OK for the file. uname -m tells you the architecture: x86_64 means x64, aarch64 means arm64. Commands that npm installs globally land in /opt/node/bin, so add that directory to the PATH (see changing PATH) if you use global tools. If node -v fails with version `GLIBC_2.28' not found, the operating system is too old for current builds; check the Linux version and move to a supported release.
How do I install Node.js on Windows and Windows Server?
- Windows 10 and 11:
winget install OpenJS.NodeJS.LTS, or the LTS installer from nodejs.org. - Windows Server 2022 and 2019: winget is not part of these, so use the Windows Installer (
.msi). Download it with Edge on Server 2022, or let PowerShell fetch the newest LTS build and install it silently:
$ProgressPreference = 'SilentlyContinue'
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
$rel = (Invoke-RestMethod https://nodejs.org/dist/index.json -UseBasicParsing) |
Where-Object { $_.lts } |
Sort-Object { [version]$_.version.TrimStart('v') } -Descending |
Select-Object -First 1
$v = $rel.version
$p = "$env:TEMP\node-$v-x64.msi"
Invoke-WebRequest "https://nodejs.org/dist/$v/node-$v-x64.msi" -OutFile $p -UseBasicParsing
$r = Start-Process msiexec.exe -ArgumentList "/i `"$p`" /qn /norestart" -Wait -PassThru
"Node.js $v, msiexec exit code: $($r.ExitCode)"
Remove-Item $pindex.json is the machine-readable list of every release on nodejs.org; its lts field holds the codename on LTS releases. Exit code 0 means installed. The MSI puts Node.js into C:\Program Files\nodejs and adds it to the PATH, so open a new PowerShell window and check with node -v, npm -v and where.exe node. Windows Server’s default execution policy, RemoteSigned, lets npm.ps1 run; on Windows 10 and 11 PowerShell may refuse it, and the fix is in the npx guide. The installer’s optional “tools for native modules” step pulls in compilers and Python for packages that build C++ code; leave it off unless a package asks for it.
On macOS, the .pkg installer from nodejs.org, nvm as above, or Homebrew all work. brew install node follows the newest release rather than LTS, and a versioned formula such as node@24 is not linked onto the PATH by itself; the npx guide has the PATH line for it.
How do I check which Node.js version is installed?
node -v # same as node --version
npm -v
npx -v
node -p process.release.lts # LTS codename, or undefined
type -a node # every node on the PATH; the first one runs (Linux, macOS)
where.exe node # the same on Windows$ node -v
v25.7.0
$ npm -v
11.10.1
$ node -p process.release.lts
undefinedNode.js 25 is an odd-numbered line, so process.release.lts is undefined; on Node.js 24 the same command prints Krypton. A version number that starts with an odd major, or with 20 or lower, is your cue to update (below). When two methods are mixed, say NodeSource in /usr/bin and nvm in your home directory, type -a node lists both, and a systemd service may run a different Node than your shell. With nvm, nvm ls shows every installed version and which one is the default.
How do I update Node.js?
| Installed with | Newer release, same major | New major version |
|---|---|---|
| NodeSource | sudo apt update && sudo apt install --only-upgrade nodejs | Run the new major's setup script (setup_26.x), then sudo apt install -y nodejs |
| nvm | nvm install 24 | nvm install --lts --reinstall-packages-from=current |
| Official binaries | Unpack the newer archive into a fresh /opt/node | The same, from latest-v26.x |
| Windows MSI | Run the newer MSI; it upgrades in place | The same, or winget upgrade OpenJS.NodeJS.LTS where winget exists |
| Distribution package | Security fixes arrive with apt upgrade | Switch to NodeSource or nvm |
nvm install 24 fetches the newest 24.x even when an older 24.x is installed. --reinstall-packages-from=current carries your global npm packages over to the new version. Afterwards, nvm alias default 24 (or nvm alias default 'lts/*' to follow future LTS lines) makes new shells use it, and nvm uninstall 22 removes the old one once nothing needs it.
After a major upgrade: rebuild native modules
Packages with compiled C++ parts (database drivers, image libraries, bcrypt) are built for one Node.js ABI. After a major upgrade the app may refuse to start with:
Error: The module '/srv/myapp/node_modules/better-sqlite3/build/Release/better_sqlite3.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 127. This version of Node.js requires
NODE_MODULE_VERSION 137. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).rm -rf node_modules
npm ci # reinstall what package-lock.json lists, built for this Node
sudo systemctl restart myappnode -p process.versions.modules prints the ABI number of the running Node.js (141 on the Node.js 25 above).
How do I update npm?
npm ships with Node.js, so updating Node brings a newer npm along. To update npm on its own:
npm view npm engines # which Node.js versions the newest npm supports
npm install -g npm@latest # with nvm or on Windows
sudo npm install -g npm@latest # with NodeSource: npm lives in /usr/lib/node_modules
npm -vCheck the engines line first: each npm major drops old Node.js lines, and the newest npm on an old Node either refuses to run or warns on every command. In that case update Node.js instead, or stay within a major with npm install -g npm@11. On Windows, if npm -v still shows the old version afterwards, where.exe npm shows which copy runs first; installing the newer Node.js MSI is the simplest way out.
How do I keep a Node.js app running on a server?
node server.js in an SSH session stops when the session ends. Use a systemd unit, which needs nothing extra, or pm2, a process manager from npm. Pick one of them, not both.
[Unit]
Description=My Node.js app
After=network-online.target
Wants=network-online.target
[Service]
User=myapp
WorkingDirectory=/srv/myapp
Environment=NODE_ENV=production
ExecStart=/usr/bin/node server.js
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now myapp
journalctl -u myapp -fExecStart needs an absolute path, which is why the NodeSource install in /usr/bin is the easy case. With nvm, the unit calls nvm-exec instead (how). Users, secrets in environment files and restart limits are covered in how to create a systemd service. The pm2 route:
npm install -g pm2 # sudo only with NodeSource, never with nvm
pm2 start server.js --name myapp
pm2 startup systemd # prints one command: run it as shown
pm2 save # the list of apps pm2 restores at boot
pm2 logs myapppm2 itself runs from a systemd unit that pm2 startup creates, with the PATH of your Node.js written into it. After a major Node.js upgrade with nvm, run pm2 unstartup and pm2 startup again so it points at the new version. A web app normally listens on 127.0.0.1:3000 with nginx in front for HTTPS (reverse proxy with SSL); a bot needs no open port at all (hosting a Discord bot on a VPS).
Common errors when installing Node.js
| Message | Cause | Fix |
|---|---|---|
nvm: command not found | The shell has not loaded nvm | Open a new terminal, then fix the startup file |
npm: command not found | Distribution nodejs package, which has no npm | Switch to NodeSource |
EACCES: permission denied, mkdir '/usr/lib/node_modules/…' | npm install -g without root on a system-wide Node.js | sudo for that one command, or nvm |
sudo: npm: command not found | sudo cannot see nvm's Node.js | Drop sudo; nvm needs none |
trying to overwrite '/usr/include/node/common.gypi' | Old libnode-dev left behind | Remove nodejs, npm and libnode-dev, then install |
npm WARN EBADENGINE Unsupported engine | A package wants another Node.js major | Read engines in its package.json, install that major |
JavaScript heap out of memory | A build ran past V8's heap limit | NODE_OPTIONS=--max-old-space-size=2048, plus swap |
yarn: command not found | Yarn is not part of Node.js | Enable it with Corepack or npm |
Running Node.js on a VPS
On a Linux VPS with Ubuntu or Debian you have root, so every method above works; for a server that only runs your app, NodeSource plus a systemd unit is the least to maintain. Memory matters more than CPU for most Node.js apps, and builds of large front-end projects are the usual peak: if npm run build dies with “heap out of memory” or just Killed, add swap or build on a plan with more RAM. The smallest Standard KVM plan has 2 cores and 4 GB of RAM, enough for a typical API or bot. On a Windows VPS with Windows Server 2022 or 2019, use the MSI route above.
Frequently asked
Which Node.js version should I install?
An LTS (Long Term Support) release; so far every LTS line has been an even-numbered major. As of October 2026 that is Node.js 24, supported until 30 April 2028, with Node.js 26 scheduled to become LTS at the end of October 2026. Odd-numbered majors such as 25 are short-lived Current releases, and Node.js 20 reached its end of life on 30 April 2026.
How do I install Node.js on Ubuntu?
Add the NodeSource repository with its setup script (setup_lts.x, or setup_24.x to stay on one major), then run sudo apt install nodejs. That one package contains node, npm and npx in /usr/bin. Ubuntu's own nodejs package is old (Node.js 12 on 22.04, 18 on 24.04) and ships npm as a separate package.
How do I update Node.js?
It depends on how you installed it. With nvm, run nvm install --lts --reinstall-packages-from=current. With NodeSource, sudo apt install --only-upgrade nodejs updates within the major; for a new major, run that major's setup script and install nodejs again. On Windows, run the newer MSI. After a major upgrade, reinstall node_modules so native modules are rebuilt.
How do I update npm?
Run npm install -g npm@latest, with sudo only when Node.js came from NodeSource or another system-wide package and never with nvm, then check with npm -v. Run npm view npm engines first: each npm major drops old Node.js versions, and on an old Node.js the better fix is updating Node.js itself, which brings a matching npm.