process.version
Returns the Node.js version string of the running process, prefixed with 'v'.
process.version- Added in Node.js v0.1.3
Return value
stringThe Node.js version string, for example 'v22.11.0', including the leading 'v'.
process.version is the Node.js version of the process that is executing your code, formatted the way the release tags are: a leading v followed by MAJOR.MINOR.PATCH, plus a pre-release suffix such as -pre or -nightly... on unreleased builds.
When to reach for it
Use it in diagnostics — a --version banner, a crash report, a support bundle — and for a hard guard at startup when your code genuinely cannot run on older releases.
What trips people up
- The leading
v.parseFloat(process.version)givesNaN, and comparingprocess.version >= '18.0.0'compares strings, so'v9.0.0'beats'v20.0.0'. Use process.versions.node for the bare number, or split and compare numerically. - String comparison is not version comparison even without the prefix:
'20.10.0' < '20.9.0'is true lexically. - Version gates age badly. A feature back-ported to an LTS line will be present in a version your check rejects. Prefer detecting the thing you need —
typeof structuredClone === 'function','parseArgs' in require('node:util')— and keep version checks for coarse support policy, not for capabilities.
Declaring an engines field in package.json lets the package manager warn before your code even runs.
Example
When to use it
- Print the runtime version in a CLI's --version output or a crash report.
- Refuse to start with a clear message when the installed Node is older than the project's minimum.
- Record the exact runtime in build metadata so a failing CI job can be reproduced.
- Log the version alongside a native module load failure to explain an ABI mismatch.
Frequently asked questions
How do I get the Node version without the leading v?
Use process.versions.node, which is the same value as a bare `MAJOR.MINOR.PATCH` string. `process.version.slice(1)` works too, but reading it from process.versions makes the intent obvious.
Why does comparing process.version with >= give the wrong answer?
Because it compares strings character by character, so 'v9.0.0' is greater than 'v20.0.0' and 'v20.9.0' is greater than 'v20.10.0'. Split process.versions.node on dots, convert each field with Number(), and compare major, then minor, then patch.
Should I check process.version to decide if a feature is available?
Usually no — test for the feature directly, for example `typeof fetch === 'function'`, because features are sometimes back-ported to older LTS lines and a version gate would wrongly reject them. Keep version checks for stating your project's overall support policy.
More examples
A minimum-version guard that compares numerically
The output shows the guard passing and failing. Comparing field by field is what makes it correct: the naive `process.version >= 'v20.6.0'` string comparison would accept v18 (because '1' < '2' never gets evaluated the way you expect) and reject v20.10.0, since lexically '10' sorts before '6'. Exiting with code 1 lets an installer or CI step stop the run.
const MINIMUM = [20, 6, 0];
const current = process.versions.node.split('.').map(Number);
function isAtLeast([reqMajor, reqMinor, reqPatch], [major, minor, patch]) {
if (major !== reqMajor) return major > reqMajor;
if (minor !== reqMinor) return minor > reqMinor;
return patch >= reqPatch;
}
if (!isAtLeast(MINIMUM, current)) {
console.error(
`This tool needs Node ${MINIMUM.join('.')} or newer; you are running ${process.version}.`
);
process.exit(1);
}
console.log(`running on ${process.version} - ok`);
// running on v22.11.0 - ok
// or, on an old runtime:
// This tool needs Node 20.6.0 or newer; you are running v18.19.1.Feature detection instead of a version number
The output shows four checks agreeing on a current runtime, which is exactly why the difference is easy to miss. They diverge on the edges: `util.parseArgs` landed in v18.3.0, so the major-version check accepts v18.0.0 where the capability check correctly reports false, and features back-ported into an older LTS line are found by the capability check but rejected by the version gate.
const util = require('node:util');
// Fragile: a back-port makes this reject a runtime that has the feature.
const byVersion = Number(process.versions.node.split('.')[0]) >= 18;
// Robust: ask for the capability itself.
const hasParseArgs = typeof util.parseArgs === 'function';
const hasStructuredClone = typeof structuredClone === 'function';
const hasFetch = typeof fetch === 'function';
console.log({ byVersion, hasParseArgs, hasStructuredClone, hasFetch });
// { byVersion: true, hasParseArgs: true, hasStructuredClone: true, hasFetch: true }
Discussion