Installing Node.js

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against Node.js 26.10.0 (Current, becoming LTS on 2026-10-28), Node.js 24.21.0 "Krypton" (Active LTS) and Node.js 22.23.3 "Jod" (Maintenance), all checked on 2026-10-03. Every command was run with those three lines. The only APIs touched are the process.release and process.versions properties (Stable) and the npm engines field. Installing Node.js is the first step of the Bookshelf application that grows across this section, and the choices made here (how Node is installed, how its version is pinned) decide whether the same code runs identically on a laptop, in CI and in a container.

Ways to get Node.js

Node.js is a single executable (node) plus the bundled npm. Every installation route ends with the same two commands working, which are also the quickest sanity check:

node -v
npm -v

On Node.js 26.10.0 they print v26.10.0 and 11.19.1; on 24.21.0 they print v24.21.0 and 11.19.0; on 22.23.3 they print v22.23.3 and 10.9.9. The routes differ in who controls the version and how it is upgraded:

Table 1. Installation routes compared
Route Good for Trade-off

Official installer (.pkg, .msi)

A single machine-wide Node.js, no tooling to learn.

One version at a time; upgrades are manual and system-wide.

Prebuilt binaries (tarball or zip)

Servers, CI images, air-gapped hosts; you control where the files go.

You manage PATH and upgrades yourself. Verify the signed SHASUMS file published next to each release.

System package managers (Homebrew, Chocolatey, winget, and similar)

Fits existing machine provisioning.

Their packaging is not maintained by the Node.js project; the version you get is what the package ships.

Version managers (nvm, fnm, Volta, asdf, n)

Developers who switch between projects on different Node lines.

Per-user, per-shell installs; not a production deployment mechanism.

Official Docker images

Reproducible CI and production runtime.

You choose a base variant (Debian, slim, Alpine) and own the image updates.

The Download page of nodejs.org generates the exact snippets for your operating system and lists the installer, standalone binary and package manager variants for each release. It also links the source tarball, nightly builds and the unofficial builds for other platforms.

Installers and prebuilt binaries

The installers are the right choice if you want one Node.js and do not want to manage versions. The prebuilt binaries are archives you unpack anywhere; Node.js needs no installation step beyond placing bin/node (and npm) on PATH. Checking a download against the signed checksums is the supported way to establish that the archive is genuine.

Verify a downloaded archive (replace the placeholders)
curl -fsSLO https://nodejs.org/dist/v{version}/node-v{version}-linux-x64.tar.xz
curl -fsSLO https://nodejs.org/dist/v{version}/SHASUMS256.txt
grep " node-v{version}-linux-x64.tar.xz$" SHASUMS256.txt | sha256sum -c -

The {version} placeholders are literal: substitute a real version such as one listed on the releases index. The same index is available as JSON at https://nodejs.org/dist/index.json, which version managers and CI setup actions read.

System package managers

The Node.js site lists the package-manager routes under its Install Node.js via package manager page. They are convenient but community-maintained, so the version you receive depends on the package. A Homebrew formula, for example, is versioned by major line (node@24), which pins the line but not the patch release.

Install a specific line with Homebrew, then check it
brew install node@24
node -v

On Windows the same page offers Chocolatey (choco install nodejs) and the Windows Package Manager (winget); for Linux it points to the distribution’s own packages and to the NodeSource and binary-distribution alternatives. Because distribution packages often lag behind the release lines, check node -v after installing and prefer a version manager or the official image when you need a specific line.

What node -v and npm -v tell you

Besides the version, the runtime tells you whether you are on a long-term support line. process.release.lts is the codename on LTS lines and is undefined on a Current line:

Which line is this, and which engines does it ship?
node -p "process.version + ' ' + (process.release.lts ?? 'Current')"
node -p "process.versions.v8"

Run on the three lines, the first command printed v26.10.0 Current, v24.21.0 Krypton and v22.23.3 Jod. Node 26 also has no codename yet, because the schedule assigns it when LTS starts. The relation between lines and support dates is covered on Release Lines & LTS.

Version managers

Different projects pin different Node lines, so developers usually install a version manager and let each project choose. All of them install under the user’s home directory and switch the active node by changing PATH, so no administrator rights are needed.

nvm

nvm is a POSIX shell function, so it works in bash, zsh and similar shells (not natively in PowerShell). The Node.js download page shows the install script pinned to an nvm release; the one tested here was nvm 0.40.4.

Install and use Node.js versions with nvm
nvm install 26
nvm install 24
nvm install 22
nvm use 24
nvm ls
nvm alias default 24

nvm use with no argument reads a .nvmrc file in the current directory (or a parent). The file holds one version specifier: a major (24), a full version (24.21.0), or an alias such as lts/* or an LTS codename.

Pin a project with .nvmrc
echo 24 > .nvmrc
nvm use
echo lts/jod > .nvmrc
nvm use

The two nvm use calls printed Now using node v24.21.0 (npm v11.19.0) and Now using node v22.23.3 (npm v10.9.9). nvm only reads .nvmrc when asked; it does not switch automatically when you cd, unless you add a shell hook.

fnm and Volta

fnm (Fast Node Manager) is a single binary, so it also runs on Windows natively (winget install Schniz.fnm is the command shown on the Node.js download page). It reads the same .nvmrc files, and can also read .node-version and the engines field when configured to. Volta takes a different approach: it installs shims for node, npm and package binaries and records the pinned versions in package.json under a volta key, so every contributor, and CI, resolves the same toolchain without a shell function. I did not install fnm or Volta in the scratch environment, so their exact options are not reproduced here; follow each project’s own documentation for flags.

Table 2. Version manager comparison
Tool Pin file Notes

nvm

.nvmrc

Shell function; macOS, Linux and WSL; needs a hook for automatic switching.

fnm

.nvmrc, .node-version

Single binary; Windows, macOS, Linux.

Volta

volta key in package.json

Shims; also pins npm and global tools per project.

asdf, n

.tool-versions (asdf)

General-purpose or minimal managers listed on the Node.js download page.

Pinning in package.json: engines

A pin file tells a version manager what to install. The engines field in package.json states what the package supports, and npm checks it. By default a mismatch only prints a warning; with engine-strict=true in .npmrc it becomes an error.

package.json
{
  "name": "bookshelf",
  "private": true,
  "engines": { "node": ">=24.12.0 <27" }
}

Running npm install under Node 22 with engine-strict=true stopped with npm error code EBADENGINE and Unsupported engine, listing the required range and the actual versions. Under Node 26 the same install succeeded. Without engine-strict, Node 22 produced only an EBADENGINE warning and the install went ahead.

Make the engines field enforced (.npmrc)
engine-strict=true

Use the three together: .nvmrc or volta for developers, engines for dependants and installers, and the Docker base image tag (below) for production. Keep them on the same line, otherwise tests pass on one Node and the container runs another.

Official Docker images

The Node.js project maintains the node image on Docker Hub. Tags follow node:<version> plus an optional variant: the default Debian-based image, -slim (fewer packages), -alpine (musl libc, noticeably smaller) and the Debian-release variants (-bookworm, -trixie). The node:lts tag follows the Active LTS line. Pinning at least the major, for example node:24-slim, avoids a surprise upgrade; pinning the digest makes the build fully reproducible.

Check what a tag contains
docker run --rm node:26-slim node -p "process.version"
docker run --rm node:24-alpine node -p "process.version"
docker run --rm node:22 node -p "process.version"

These printed v26.10.0, v24.21.0 and v22.23.3, all on linux arm64 (the architecture of the machine used; the images are multi-architecture). The images ship a non-root user named node (uid 1000), which a production Dockerfile should select with USER node.

Minimal runtime image for the Bookshelf app
FROM node:24-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY src ./src
USER node
CMD ["node", "src/server.js"]

Alpine images use musl instead of glibc, so native add-ons built for glibc may not run there, and tools such as bash and git are not included. Use -slim when in doubt. The Docker concepts themselves (layers, multi-stage builds, registries) are in Docker: Getting Started.

Windows and WSL

On Windows you have two reasonable setups. Native Windows uses the official .msi installer, winget, Chocolatey or fnm; commands run in PowerShell or Command Prompt and paths use backslashes. Windows Subsystem for Linux (WSL) runs a real Linux distribution, so everything on this page for Linux applies unchanged, including nvm. Production servers are almost always Linux, so developing inside WSL removes a class of differences: path separators, file-permission bits, case-sensitive file names, shell syntax in package.json scripts, and native add-ons.

Table 3. Native Windows or WSL
Aspect Native Windows WSL

Install

.msi, winget, Chocolatey, fnm

Same as Linux: nvm, fnm, distribution packages

Shell scripts in npm scripts

Run through cmd.exe by default; POSIX syntax may break

Run through sh, as in production

File performance

Good on C:

Keep projects on the Linux filesystem, not under /mnt/c

Version manager

fnm or Volta (nvm is a separate Windows project)

nvm, fnm, Volta

Keep one Node installation per environment. A Windows node and a WSL node are different programs with different global packages.

Corepack, pnpm and Yarn

npm is bundled with Node.js. pnpm and Yarn are not. Until Node.js 24, Corepack, a small tool bundled with Node that provisions the package manager named in the packageManager field of package.json, shipped inside the distribution, and corepack enable created the pnpm and yarn shims.

Starting with Node.js 25.0.0 (2025-10-15), Corepack is no longer distributed with Node.js. This is a semver-major build change (the release notes list "stop distributing Corepack"). Node 26 therefore has no corepack command: on Node 26.10.0, which corepack finds nothing, while on 24.21.0 and 22.23.3 it still resolves from the bundled copy (Corepack version 0.36.0 on 24.21.0). The Node.js documentation page for Corepack now redirects to the Corepack repository.

Table 4. Package manager provisioning by Node.js line
Line What you get

Node 22 and 24

Bundled corepack; corepack enable pnpm works out of the box.

Node 25 and 26

No bundled Corepack. Install it yourself, or install the package manager directly.

There are two supported ways forward. The first keeps the Corepack workflow and installs Corepack from npm; this is exactly what the Node.js download page now shows:

Keep the packageManager workflow on Node 26
npm install -g corepack
corepack enable pnpm
pnpm -v

npm install -g corepack installed version 0.36.0 (run here with --prefix into a scratch directory so no global state changed). With a "packageManager": "pnpm@<version>" field in package.json, the resulting pnpm shim then runs the pinned version, which is how teams keep every contributor on one package manager version.

The second route skips Corepack and installs the package manager as an ordinary package, or with its own standalone installer:

Install pnpm and Yarn as normal global packages
npm install -g pnpm
npm install -g @yarnpkg/cli-dist
yarn -v

Both installs worked on Node 26; @yarnpkg/cli-dist provided the modern Yarn (4.18.1 on 2026-10-03), whereas the npm package named yarn is still Yarn Classic (1.22.22). Installing pnpm with npm 11 also printed a warning about install scripts and the allow-scripts setting; follow the hint printed by npm if the package needs it. Note that pnpm read the packageManager field of the project it was run in and ran the pinned version, so a lockstep version in package.json still applies. Which of the two ways to choose is a team decision: Corepack gives per-project version pinning, direct installs give fewer moving parts. The tools' own installation pages lean towards their preferred routes: on 2026-10-03 the pnpm page offered a standalone installer (npx get-pnpm, which needs Node.js 22.13 or newer) and install scripts rather than npm install -g pnpm, and the Yarn page recommended installing Corepack with npm install -g corepack and pinning Yarn per project (yarn init -2, yarn set version stable) rather than a global Yarn.

What changed recently

  • Node.js 25.0.0 (2025-10-15): Corepack is no longer distributed; corepack must be installed from npm (see above). Node 25 is end-of-life (2026-06-01).

  • Node.js 26 (Current): no codename yet; LTS begins 2026-10-28 and Maintenance 2027-10-20. It bundles npm 11.19.1.

  • npm releases: npm 12 is the latest tag on the registry (12.2.0) but is not bundled with any Node line, so npm install -g npm@latest upgrades past what Node ships. Node 22 still ships npm 10.9.9.

  • Node.js 24 "Krypton": Active LTS until 2026-10-20, then Maintenance; end-of-life 2028-04-30.

  • Node.js 22 "Jod": Maintenance; end-of-life 2027-04-30. Node 20 reached end-of-life on 2026-04-30.

  • Node.js 27: the first line under the new annual model (alpha from 2026-10-28), where every line becomes LTS.

See Upgrading & What’s Changed for the full list of breaking changes between lines.

Where the books are outdated

The installation chapter of Efficient Node.js by Samer Buna (O’Reilly, 2025) describes installing through the installer, Homebrew, nvm and WSL, which is still sound, but its release-line guidance predates Node 25 and 26, so check the dates above. The appendix of Node.js Projects by Jonathan Wexler (O’Reilly, 2025) shows enabling Yarn through Corepack; on Node 25 and later that command no longer exists until Corepack is installed from npm. Treat any corepack enable instruction from older material as requiring the extra install step on current Node.