On October 21, 2026, Node.js released security patches for ten vulnerabilities affecting its supported versions, four of them rated high, including a remote code execution issue. Unsupported versions, such as Node.js 20 and 25, won't be updated.
Keeping Node.js up to date isn't optional: it's worth spending some time on it, both on your personal computer and on your server. The easiest way is to let the operating system handle those updates for you. To do that, install Node.js with apt from the NodeSource repository and let sudo apt upgrade take care of the rest.
Now that Node.js 26 (Lithium) has been LTS since October 28, 2026 and Ubuntu 26.04 LTS (Resolute Raccoon) has been out for months, it's a good time to get it properly installed. The recipe is the same as in my Node.js 24 on Ubuntu 24 guide.
Both releases have long support windows, so this setup will last for a while:
| Release | Released | LTS / standard support | End of life |
|---|---|---|---|
| Node.js 26 (Lithium) | May 5, 2026 | Active LTS from Oct 28, 2026 | April 30, 2029 |
| Ubuntu 26.04 LTS | April 23, 2026 | Standard support until April 2031 | ESM with Ubuntu Pro for 10 years |
Node.js 26 moves to maintenance on October 20, 2027 (see the official release schedule), and it's the last release under the odd/even model: from Node.js 27 onwards, the project ships one major release per year and every release becomes LTS. If you're still on Node.js 24, don't panic: it's supported until April 2028 (and Node.js 22 until April 2027).
Most of the steps are the same, but there is one important change: Corepack is no longer bundled with Node.js. It was removed in Node.js 25, so corepack enable doesn't work on a fresh Node.js 26 install. The Node.js docs point to the userland corepack package if you still want it.
I took the simplest route and now install pnpm with its own standalone installer. If you use Yarn, you can install the corepack package globally (see below).
As before, you can install everything with a single command. The script installs Node.js 26 from NodeSource, configures a global npm prefix (so you don't need sudo for global packages), and can optionally install pnpm and Bun.
curl -fsSL https://angelblanco.dev/scripts/ubuntu-install-node-26.sh | bash
The script asks for confirmation at each major step. As always, read the script before you pipe it into bash. Running random scripts from the internet is a fun hobby until it isn't.
If you don't have curl installed:
sudo apt update
sudo apt install curl
Here's what the script does, in case you want to run it step by step.
First, install the tools needed to download and verify packages:
sudo apt update
sudo apt install -y ca-certificates curl gnupg
Then add the NodeSource repository for Node.js 26:
curl -fsSL https://deb.nodesource.com/setup_26.x | sudo -E bash -
NodeSource uses a single nodistro suite for every Debian-based distribution, so it works on Ubuntu 26.04 without waiting for a codename-specific repository. The setup script also adds an apt pin with priority 600, so the NodeSource package always wins over the nodejs package from the Ubuntu archive. Without it, you could end up with an older Node.js from the Ubuntu repositories.
sudo apt-get install -y nodejs
node --version
This installs both the node runtime and npm.
To install global packages without sudo, set up a directory in your home folder:
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
Then add it to your PATH in ~/.bashrc or ~/.zshrc:
export PATH=~/.npm-global/bin:$PATH
Since Corepack is no longer included, install pnpm with its standalone script:
curl -fsSL https://get.pnpm.io/install.sh | sh -
The installer adds pnpm to your PATH in your shell config, so open a new terminal (or source your config file) before you run pnpm --version. From then on, pnpm self-update keeps it up to date.
If you want to try Bun, use its official installer, which needs unzip:
sudo apt install -y unzip
curl -fsSL https://bun.sh/install | bash
If your projects use Yarn, you can still use Corepack. You just need to install it yourself:
npm install -g corepack
corepack enable
Because we configured a global npm prefix, this works without sudo. Keep in mind that the Corepack package is now maintained outside the Node.js release cycle, so check its README if something behaves unexpectedly on Node.js 26.
This is the complete script. It includes confirmations, uses a temporary directory that is removed on exit, and reads your answers from the terminal, so it works when you pipe it from curl.
This script comes from my Neovim configuration repo, where I keep my install scripts. The editor needs Node.js for several language servers and plugins, so I update them regularly. If you want the latest version, look there first.
#!/bin/bash
#
# Author: Ángel Blanco
# License: MIT
#
# This script is provided "as is", without warranty of any kind. Use at your own risk.
#
# Source: https://angelblanco.dev/blog/apt-install-node-26-on-ubuntu-26
#
# Usage:
# curl -fsSL https://angelblanco.dev/scripts/ubuntu-install-node-26.sh | bash
#
# This script installs Node.js and several package managers.
# Run it as your non-root user: it asks for elevated permissions
# with sudo when needed.
#
set -e
# Basic confirmation module before executing the script.
confirm_action() {
read -p "$1 (y/n): " choice < /dev/tty
case "$choice" in
[Yy]|[Yy][Ee][Ss])
return 0
;;
[Nn]|[Nn][Oo])
return 1
;;
*)
echo "Invalid choice. Please enter 'y' or 'n'."
confirm_action "$1"
;;
esac
}
# You can configure these variables if needed
NODE_VERSION=26
NPM_PREFIX="~/.npm-global"
DEPS="ca-certificates curl gnupg"
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
echo "This script will install Node.js and optionally other package managers."
echo ""
if ! confirm_action "Install Node.js version $NODE_VERSION?"; then
echo "Skipping Node.js installation. Exiting."
exit 0
fi
echo "Installing the dependencies needed to install Node.js..."
sudo apt update
sudo apt install -y $DEPS
echo "Installing Node.js..."
curl -fsSL https://deb.nodesource.com/setup_$NODE_VERSION.x -o $TMP_DIR/nodesource_setup.sh
sudo -E bash $TMP_DIR/nodesource_setup.sh
sudo apt-get install -y nodejs
mkdir -p ~/.npm-global
npm config set prefix $NPM_PREFIX
echo "npm prefix set to $NPM_PREFIX"
echo "Node.js installation completed."
echo "Node version: "
node --version
echo ""
if confirm_action "Install pnpm?"; then
echo "Installing pnpm..."
curl -fsSL https://get.pnpm.io/install.sh | sh -
echo "pnpm installation completed. Open a new terminal (or source your shell config) to use it."
fi
echo ""
if confirm_action "Install Bun?"; then
echo "Installing Bun..."
sudo apt install -y unzip
curl -fsSL https://bun.sh/install | bash
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
echo "Bun version: "
bun --version
fi
echo ""
echo "Installation process finished."
echo ""
echo "Add the global npm bin directory to your PATH by adding this line to your .bashrc or .zshrc:"
echo 'export PATH=~/.npm-global/bin:$PATH'
echo ""
echo "Node.js now comes from apt, so keep it patched with:"
echo "sudo apt update && sudo apt upgrade"
echo ""
Once it's installed, keeping it up to date takes just a couple of commands:
# Operating system and Node.js
sudo apt update && sudo apt upgrade
# Package managers
pnpm self-update
bun upgrade
npm update -g
And don't forget your project dependencies: pnpm outdated and pnpm audit tell you what needs updating.
That's also why I still don't use NVM day to day, as I explained in the previous post. It's great if you really need several Node.js versions side by side, but every version you install with NVM is one more you have to remember to patch.
With AI speeding up how fast vulnerabilities are found and exploited, and security breaches that keep popping up, staying up to date has to be as easy as possible. Because now, more than ever, it's not optional.