How to Define Node.js Versions in package.json

Your package.json file can pin the Node.js version a project needs, and npm checks it on every install. The engines field holds that version, and one line in .npmrc makes npm enforce it instead of just warning.

Why Define a Node Version in package.json

Node.js releases move fast, and a project written for one LTS line can break on another. Native modules refuse to compile, APIs get removed, and the same code that worked yesterday fails after an upgrade. When you share your project, whoever clones it has no idea which version you built it against until something breaks.

The engines field fixes this. You declare the supported Node.js and npm versions once, and every person (and CI server) that installs the project gets checked against your range automatically.

The engines Field

Open package.json and add an engines object with a node key, using standard semver ranges:

{ “name”: “my-app”, “version”: “1.0.0”, “engines”: { “node”: “>=26.0.0”, “npm”: “>=11.0.0” } }

Any valid semver range works here. These are the ones you will use most:

  • “node”: “>=20.13.0” accepts any version at or above 20.13.0.
  • “node”: “~26.7.0” accepts only patch updates within 26.7.x, useful when a native dependency is picky.
  • “node”: “>=20 <27" combines two bounds so both too-old and too-new versions are rejected.
  • “node”: “*” or a missing engines field means any Node.js version is fine.

You can also constrain npm itself with an npm key, which matters because engine behavior changed across npm major versions.

Default Behavior Is Only a Warning

By default, npm treats engines as advisory. I verified this on Node.js v26.7.0 with npm 11.19.0: a package declaring “node”: “<20.0.0” still installs cleanly, but prints this warning:

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: '[email protected]',
npm warn EBADENGINE   required: { node: '<20.0.0' },
npm warn EBADENGINE   current: { node: 'v26.7.0', npm: '11.19.0' }
npm warn EBADENGINE }

The install succeeds despite the mismatch. That warning scrolls past in CI logs and nobody reads it. If you want the check to actually stop bad installs, add one more file.

Enforce It with .npmrc

Create a .npmrc file next to package.json with one line:

engine-strict=true

.npmrc is npm’s configuration file, and engine-strict=true flips the engines field from advisory to enforced. Now the same mismatched install fails hard:

npm error code EBADENGINE
npm error engine Unsupported engine
npm error engine Not compatible with your version of node/npm: [email protected]
npm error notsup Required: {"node":"<20.0.0"}
npm error notsup Actual:   {"node":"v26.7.0","npm":"11.19.0"}

The command exits with code 1 and nothing installs.

With a matching range such as “node”: “>=26.0.0” on v26.7.0, npm install completes silently instead.

Commit .npmrc to your repository.

The setting is per-project, so enforcement travels with the code only if the file does.

What engines Does Not Do

The check runs during npm install, not when you run node index.js. Someone who already installed dependencies can still launch your app on the wrong runtime.

engines only reports a mismatch. To change the installed version, use a version manager such as nvm or follow How to Downgrade Node Version: 3 Easy Ways.

Newer npm versions also support a devEngines field for teams working directly on a codebase, with keys like runtime and packageManager and per-rule onFail behavior. For published libraries, engines remains the standard contract with your users.

If you are new to npm’s ecosystem, NodeJS NPM: A Beginner’s Guide to Node Package Manager covers how packages and package.json fit together.

Summary

Add an engines object to package.json with semver ranges for node (and optionally npm), then commit a .npmrc containing engine-strict=true so violations fail the install instead of logging a warning. Declare the range honestly from the oldest version you actually test against, and every clone, CI run, and deploy will catch the wrong runtime before your app does.

Snigdha Keshariya
Snigdha Keshariya

Snigdha Keshariya covers AI concepts and tools, from AI agents, RLHF, prompting, and model architectures to coding assistants and AI productivity tools.

Articles: 111