How to Check Your Node Version (and Why It Matters More Than You Think)

Sean

Platform Writer

Jun 09, 2026
8 min read

Most developers find out which Node version they are running the wrong way. They paste node -v into a terminal, screenshot the result, and move on. The version printed there is only one of at least four versions that matter on a real project, and the gaps between them are where build failures and “works on my machine” tickets are born.

node -v is the fast answer. The complete answer involves your shell, your project files, your package manager, your CI, and your production host. This post walks through the quick check, the versions that actually matter, the traps that cause drift between them, and the small habits that keep the whole stack honest.

How to check your Node.js version across local, project, CI, and production environments

The direct answer

To check your Node.js version, run node -v (or node --version) in your terminal. On Windows, macOS, and Linux the output is the same: a single line like v22.11.0 that tells you which V8 build your current shell session is using. That is enough to confirm Node is installed and roughly current. It is not enough to know what your project will actually run on.

If node is not found, you are not dealing with a version problem. You are dealing with an installation problem, and you need to install Node first (the official binary, a version manager, or your platform’s package manager) before any version check makes sense.

The four versions that actually matter

A Node project lives in at least four places, and each one can quietly disagree with the others.

  1. Your shell — the binary your terminal is calling right now (node -v).
  2. Your project — the version declared in package.json under engines.node, the engines field your CI will enforce, and a .nvmrc or .node-version file in the repo root.
  3. Your CI — the version GitHub Actions, GitLab CI, or whatever pipeline you use resolves on a fresh runner. Default runners ship with one Node version and quietly upgrade over time.
  4. Your host — the version your production service runs on. This is the one that decides whether your users see a working app or a 502.

If any two of those drift, you eventually get a deploy that passed CI and died in production. The fix is not a cleverer version check. It is a single source of truth that all four places read from.

The quick checks that solve 80% of “what version am I on”

These are the commands worth keeping in muscle memory.

node -v          # Node runtime version
npm -v           # npm version (bundled with Node)
npx -v           # npx version (also bundled)
which node       # absolute path of the node binary in use

which node is the one most people skip, and it is the one that catches the most bugs. If you have nvm, fnm, n, or asdf installed, the path will tell you which version manager the binary came from, which tells you which Node it belongs to.

For a fuller view, ask Node to dump its build configuration:

node -p "process.versions"

That prints an object with the V8 version, the OpenSSL version, the module version, and a few other numbers that are useful when a native dependency is misbehaving.

node -p "process.versions"
# {
#   node: '22.11.0',
#   v8: '12.4.254.21',
#   uv: '1.49.2',
#   zlib: '1.3.0.1-motley',
#   brotli: '1.1.0',
#   ares: '1.34.1',
#   modules: '127',
#   ...
# }

If a native package fails to install with a GLIBC or NODE_MODULE_VERSION error, the relevant number is hiding in that block, not in node -v.

Checking the version from inside a running app

Sometimes the question is not “what does my terminal see” but “what does the deployed process see.” Two reliable ways to get that answer:

# Hit an endpoint that returns runtime info
curl -s https://your-app.example.com/health | jq

# Or read the process directly
node -e "console.log(process.version, process.platform, process.arch)"

A /health route that returns the Node version, git SHA, and uptime is a small habit that pays for itself the first time a customer reports a bug and you need to know whether they are on the canary or the stable release.

Locking the project to a version

Once you know what is running, the next step is to stop the project from being polite about it. Three small files do most of the work.

.nvmrc — what nvm and fnm read when you cd into the project.

22.11.0

package.json engines field — what npm respects when you set engine-strict=true in .npmrc.

{
  "engines": {
    "node": ">=20.0.0 <23.0.0"
  }
}

volta or n pin in package.json — if you use Volta to manage versions, the volta field pins Node and your package manager per project without a separate file.

Pick one. The mistake is using two. If .nvmrc says 22.11.0 and engines says >=18.0.0, you have not actually locked anything.

The CI trap

A team pins Node in package.json, ignores .nvmrc, and watches CI drift anyway. It happens because GitHub Actions and GitLab CI default to whatever Node version is installed on the runner image, and runner images get upgraded silently.

The fix is one line in your CI config that reads from the project, not from the runner:

# GitHub Actions
- uses: actions/setup-node@v4
  with:
    node-version-file: '.nvmrc'
# GitLab CI
default:
  image: node:22.11.0
# CircleCI
- node:
    version: 22.11.0

The principle is the same everywhere: the pipeline reads the version from the project, not from the runner. That is the only way to make CI respect a pin.

What “works on my machine” usually means

A bug report that says “it works on my machine” is almost always a version story. Three of the most common shapes:

  • The developer is on Node 22 with the OpenSSL 3 provider. Production is on Node 20 with OpenSSL 1.1.1. A package that worked locally throws error:0308010C:digital envelope routines::unsupported in production. Fix: align the Node versions, or move the call to use the OpenSSL 3 provider explicitly.
  • The developer has the latest version of a native module compiled against NODE_MODULE_VERSION 127. Production runs Node 18 (NODE_MODULE_VERSION 108). The module refuses to load. Fix: rebuild the native module on the production Node version, or upgrade production.
  • The developer installed a package with npm install (which respects the lockfile). CI uses npm ci (which is stricter). Production uses a Docker image with a different Node minor. Three slightly different dependency graphs. Fix: pin Node in the build image the same way you pin it locally, and rebuild native modules in that image.

None of these bugs are mysteries once you know to ask “what Node is actually running here.” The Node version is rarely the bug. The mismatch between four Node versions almost always is.

A short debugging checklist

When something looks like a Node version problem, run this in order.

  1. node -v in your terminal — confirms the local runtime.
  2. cat .nvmrc in the project root — confirms the intended version.
  3. node -p "require('./package.json').engines.node" — confirms what the package declares.
  4. In CI, echo the Node version as the first step of the job. If it does not match .nvmrc, you have found the bug.
  5. In production, hit the /health endpoint and read the version. If it does not match .nvmrc, that is the bug, and the fix is to rebuild the deploy image against the right version.
  6. If a native module is involved, check process.versions.modules in both local and prod. A mismatch there is a rebuild, not a config change.

That sequence catches the version problem in under a minute in most cases. The instinct to “just try a different version” usually wastes that minute and then some.

Where the host version hides

For a managed platform, the production version is whatever the runtime image is built against. On RunxBuild, Node services run against a pinned image per service, the same image used by the build, and the build reads the version from your .nvmrc by default. That collapses the four-version problem into one: declare the version once in the repo, and the build, CI, and runtime agree on it.

If you want to see the version that is actually running in front of users, the services workflow docs walk through how a Node service is built and deployed end to end. If you are about to pick a Node version for a new project, the hosting calculator is a fast way to see what each version costs on a small service before you commit.

FAQ

How do I check my Node version on Windows?

Open PowerShell or Command Prompt and run node -v. The output is the same as on macOS or Linux. If node is not recognized, install Node from the official Windows installer or use a version manager like fnm or nvm-windows.

What is the difference between node -v and node --version?

None. They are aliases and print exactly the same output. Use whichever you can type faster.

How do I check the npm version separately from Node?

Run npm -v. npm is bundled with Node, so the version is determined by which Node you are running. If you want a different npm version, you can install it explicitly with npm install -g npm@10 (and respect any engines.npm constraint in package.json).

What does LTS mean and should I use it?

LTS (Long Term Support) versions of Node are the recommended choice for production. They receive security and stability fixes for about 30 months. Current versions move faster and are fine for experimentation but are not the right default for a service with paying users. The Node release schedule lives on the official Node.js site.

How do I check the Node version of a deployed app?

The reliable ways are a /health endpoint that returns process.version, reading it from the host’s process list, or checking the build manifest the platform exposes. The unreliable way is to guess from the project’s .nvmrc, because the deploy image and the project file can disagree.

Can two projects on the same machine use different Node versions?

Yes, with a version manager. nvm, fnm, n, asdf, and Volta all let you keep multiple Node installs side by side. The version manager reads .nvmrc (or its equivalent) when you enter a project and switches the active binary automatically if you set up shell integration.

Why does node -v return something different inside Docker?

Because the Docker image was built with a different base. The Node inside the container is whatever the Dockerfile installed, which is independent of what is on your host. Pin the Node version in the Dockerfile (FROM node:22.11.0-bookworm-slim) and you collapse the version question to a single line in one place.

Closing thought

A version check is two keystrokes. A version strategy is a small set of files that keeps four environments honest. The difference is the difference between “the build works” and “the build works, the deploy works, and the support tickets stop.” Most Node deploy pain is solved not by upgrading Node, but by removing the room for one environment to quietly disagree with another.