The error, verbatim
Jump to the fix ↓npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: 'react-router@8.5.0',
npm warn EBADENGINE required: { node: '>=22.22.0' },
npm warn EBADENGINE current: { node: 'v22.12.0', npm: '10.9.0' }
npm warn EBADENGINE }
Tested on
- Node
- 20.18.0, 22.12.0, 24.14.0
- npm
- 10.8.2, 10.9.0, 11.9.0
- Packages
- vite 6.4.5 / 8.3.5, react-router 7.18.4 / 8.5.0
- OS
- Windows 11 Pro
Contents
A package’s package.json can say which Node versions it supports, in an engines field. When yours is outside that range, npm prints this. The two lines that matter are required (what the package asks for) and current (what you have).
By default it’s a warning: the install finishes and the package is in node_modules. I ran the same installs on Node 20.18.0 and 22.12.0, with each version’s own npm, and got four different outcomes:
| Command | Node 20.18 | Node 22.12 |
|---|---|---|
npm install react-router@8 |
EBADENGINE warning, installed 8.5.0 | EBADENGINE warning, installed 8.5.0 |
npm install react-router (no version) |
no warning, installed 7.18.4 | no warning, installed 7.18.4 |
npm install vite (no version) |
no warning, installed 6.4.5 | installed 8.3.5 |
npm install vite@8 |
npm crashed: Cannot read properties of null (reading 'edgesOut') (on November 3: an EBADENGINE warning instead, installed 8.3.5) |
installed 8.3.5 |
React Router 8 needs Node 22.22.0 or newer, and Vite 8 needs ^20.19.0 || >=22.12.0, so both Node versions were too old for one of them.
The quiet one: npm picked an older major
Without a version number, npm didn’t install the latest release at all. It picked the newest version whose engines range matched my Node: React Router 7.18.4 instead of 8.5.0, and on Node 20.18, Vite 6.4.5 instead of 8.3.5. No warning, nothing in the output.
That’s how a project ends up a major version behind its tutorial, with no error to search for. Check what you actually got:
npm ls vite react-router
Does the package still work after the warning?
It depends on the package, and the warning doesn’t say. React Router 8.5.0 loaded on both Node 20.18.0 and 22.12.0 after the warning (createBrowserRouter was there). That doesn’t make it safe: the package’s authors only promise support from 22.22.0, so the next feature you call may use something your Node doesn’t have.
The real fix is a Node version inside the required range. Check the range first:
npm view react-router@8 enginesreact-router@8.5.0 { node: '>=22.22.0' }Then install a Node version that satisfies it (with nvm, fnm, Volta or the installer from nodejs.org) and run npm install again.
If you can’t upgrade Node yet, install the last major that supports yours instead of the pinned one. Leaving out the version did exactly that: React Router 7.18.4 and, on Node 20.18, Vite 6.4.5.
When the warning becomes an error
With engine-strict turned on (--engine-strict, or engine-strict=true in .npmrc), the same install stops:
npm error code EBADENGINE
npm error engine Unsupported engine
npm error engine Not compatible with your version of node/npm: react-router@8.5.0
npm error notsup Required: {"node":">=22.22.0"}
npm error notsup Actual: {"npm":"10.8.2","node":"v20.18.0"}
Nothing was installed. If you see this in CI but only a warning on your own machine, look for an .npmrc with engine-strict=true in the project or the CI config. The fix is the same: a Node version in the required range.
The crash instead of a warning
In my first test, on Node 20.18.0, npm install vite@8 never got as far as EBADENGINE. npm itself failed with npm error Cannot read properties of null (reading 'edgesOut'). Its log showed the crash inside npm’s dependency-tree step (#loadPeerSet in build-ideal-tree.js). It happened with npm 10.8.2 and again with 10.9.0, and the same command worked on Node 22.12.0. If you get that message while installing a recent package on an old Node, check the package’s engines before debugging npm.
On November 3 the same command on the same Node 20.18.0 and npm 10.8.2 didn’t crash: it printed the normal EBADENGINE warning for vite@8.3.5 and installed it. So if you hit the edgesOut crash, it isn’t a permanent property of that Node version; an install that worked once can fail with it later, or the other way round.
How I set it up
Windows 11 Pro, October 22, 2026, with the official portable builds of Node 20.18.0 (npm 10.8.2) and 22.12.0 (npm 10.9.0) and the installed Node 24.14.0 (npm 11.9.0). Each install ran in a fresh folder, with and without a version number and with --engine-strict, and the installed version was read from node_modules afterwards. Every message above is the real output.
Re-run on November 3, 2026 on GitHub Actions ubuntu-latest with the same Node 20.18.0 (npm 10.8.2) and 22.12.0 (npm 10.9.0), plus Node 24.22.1 (npm 11.19.1). react-router@8 (now 8.5.1, node >=22.22.0) warned on 20 and 22 and installed; plain npm install react-router quietly took 7.18.5 on both; plain npm install vite took 6.4.5 on Node 20 and 8.3.5 on 22; with engine-strict=true the react-router@8 install failed with EBADENGINE and notsup Required: {"node":">=22.22.0"}; and Node 24 installed everything with no warning. The one change was the vite@8 crash, above. The script and the run are public.
— N.K., end of entry No.085