Node version errors — unsupported syntax and engine mismatches

Tell the two apart — a hard SyntaxError when your code is newer than the running Node, and the softer EBADENGINE warning — then set the right version in Settings.

Two different Node "version" problems get confused for each other. One is a hard crash — the Node you're running is older than the syntax your code uses, so it can't even parse the file. The other is just a warning from npm that a package would prefer a different Node. This guide reads both and points you at the one dial that fixes them: the version picker in Settings.

At a glance
SyntaxError at startup Running Node is too old for your code's syntax — a real crash
npm warn EBADENGINE A package prefers another Node version — only a warning
The fix Switch the Node version in Settings (any plan)

The hard one: SyntaxError

Modern JavaScript features are tied to Node versions. Run code that uses a feature your Node doesn't understand, and it fails before your code runs — the parser rejects the file. On an older Node, a class static block (a Node 16.11+ feature) crashes like this:

/home/container/index.js:2
  static {
         ^

SyntaxError: Unexpected token '{'
    at wrapSafe (internal/modules/cjs/loader.js:1029:16)

The tell is the shape: a SyntaxError pointing at a modern construct (?., ??, static blocks, top-level await, #private fields), thrown at load time. It isn't a typo — it's a version gap. The same happens with a dependency: if a package ships newer syntax than your Node, its file is the one in the stack trace.

🎯 Good to know: The default here is Node 20, which is thoroughly modern — so this usually bites only after you deliberately switch to an old version, or pull in a package that expects a newer one than you're on.

The soft one: EBADENGINE

A package can declare which Node it supports in its engines field. When yours doesn't match, npm prints a warning during install:

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: '[email protected]',
npm warn EBADENGINE   required: { node: '>=22.0.0' },
npm warn EBADENGINE   current: { node: 'v20.20.2', npm: '11.18.0' }
npm warn EBADENGINE }

Read the required vs current lines — they name the mismatch exactly. But notice what happens next: the install finishes anyway. EBADENGINE is advisory. If your app then runs fine, you can ignore it. It only becomes a real problem if that package actually uses syntax or APIs your Node lacks — at which point you get a crash (often the SyntaxError above) and the version bump is warranted.

You see Severity What to do
SyntaxError on a modern feature Crash — app won't run Move to a newer Node in Settings
npm warn EBADENGINE then a clean start Warning only Ignore, or bump to satisfy it
npm warn EBADENGINE then a crash The warning came true Bump to the required version

The fix: the version picker

Node version switching is on the Settings page (the runtime/Docker-image dropdown), on any plan — no premium needed. Versions 12 through 25 are selectable; the default is 20.

  1. Read the version your code or package needs (the required line, or the release that introduced the syntax).
  2. Open Settings, pick that Node version.
  3. Restart. The next start runs on the new version — and re-runs npm install, so native modules rebuild for it too.

⚠️ Heads up: Going older to satisfy one stubborn dependency can break others that needed the newer Node. Prefer moving up to the newest version everything supports, not down.

Beyond version selection, everything about Node itself is standard — the release notes at nodejs.org list exactly which feature landed in which version.


Next steps

Was this guide helpful?