NPM now has built-in support for enforcing a specific version of Node and NPM via the devEngines field:
"devEngines": {
"packageManager": {
"name": "npm",
"version": "11.11.0",
"onFail": "error"
}
"runtime": {
"name": "node",
"version": "24.11",
"onFail": "error"
}
}
$ npm test
npm error code EBADDEVENGINES
npm error EBADDEVENGINES The developer of this package has specified the following through devEngines
npm error EBADDEVENGINES Invalid devEngines.packageManager
npm error EBADDEVENGINES Invalid semver version "11.11" does not match "11.6.1" for "packageManager"
npm error EBADDEVENGINES {
npm error EBADDEVENGINES current: { name: 'npm', version: '11.6.1' },
npm error EBADDEVENGINES required: { name: 'npm', version: '11.11', onFail: 'error' }
npm error EBADDEVENGINES }
With either of devEngines.packageManager or devEngines.runtime specified, if there is a semver mismatch, most npm commands, including npm test will fail fast with an error.
The great thing about the field as compared to engines is that it doesn't affect downstream consumers of the published NPM package. It only applies if you're developing within a given repo.
NPM now has built-in support for enforcing a specific version of Node and NPM via the
devEnginesfield:With either of
devEngines.packageManagerordevEngines.runtimespecified, if there is a semver mismatch, mostnpmcommands, includingnpm testwill fail fast with an error.The great thing about the field as compared to
enginesis that it doesn't affect downstream consumers of the published NPM package. It only applies if you're developing within a given repo.