# Node.js: “Error [ERR_REQUIRE_ESM]: require() of ES Module... not supported”

> Error [ERR_REQUIRE_ESM]: require() of ES Module not supported. Upgrade Node.js, use import() or ES modules, or pin the last CommonJS version.

Canonical: https://app369.com/fix/node-err-require-esm/
Last updated: 2026-11-07

A require() call fails with Error [ERR_REQUIRE_ESM]: require() of ES Module ... not supported, often after updating a package such as node-fetch, chalk or nanoid. The package now ships only as an ES module, and older Node.js versions cannot load ES modules with require(). Newer Node.js versions can, with limits.

**Short answer**

Upgrade to Node.js 20.19 or 22.12 or later, where require() can load ES modules that have no top-level await (a default export then sits at .default). If you can’t upgrade, load the package with await import('pkg') inside an async function, switch your project to ES modules ("type": "module"), or pin the last CommonJS version (node-fetch@2, chalk@4). If the error comes from a tool such as Jest or ts-node, configure that tool for ES modules, because it may still use the old loader.

## **Why require() rejects the module, and the fix**

1. 01 ### **The Node.js version is too old for require(esm)**
  > “v23.0.0, v22.12.0, v20.19.0 This feature is no longer behind the --experimental-require-module CLI flag.” [**Node.js, Modules: Loading ECMAScript modules using require()**](https://nodejs.org/api/modules.html) Loading ES modules with require() is on by default from Node.js 20.19 and 22.12. On older versions the same line throws ERR_REQUIRE_ESM. Check node -v locally and on the server, CI and hosting platform, and set the version in package.json engines or .nvmrc. After upgrading, require() returns the module namespace object, so a default export is at .default: const chalk = require('chalk').default.```
node -v

// package.json
"engines": { "node": "^20.19.0 || >=22.12.0" }

// default exports sit at .default
const chalk = require('chalk').default;
```
2. 02 ### **The module uses top-level await**
  > “require() only supports loading ECMAScript modules that meet the following requirements: The module is fully synchronous (contains no top-level await)” [**Node.js, Modules: Loading ECMAScript modules using require()**](https://nodejs.org/api/modules.html) Even on new Node.js versions, require() can only load an ES module that runs synchronously. A module with top-level await (in it or in its imports) fails with ERR_REQUIRE_ASYNC_MODULE. Load it with import() instead.```
// import() works for any ES module, with or without top-level await
async function main() {
  const { default: fetch } = await import('node-fetch');
  const res = await fetch('https://example.com');
}
main();
```
3. 03 ### **Move the project to ES modules** If most of your dependencies are ES modules now, switching your own code is the lasting fix: add "type": "module" to package.json and replace require() and module.exports with import and export. Rename files that must stay CommonJS to .cjs.```
// package.json
{ "type": "module" }

// before: const chalk = require('chalk');
import chalk from 'chalk';
```
4. 04 ### **Pin the last CommonJS version** When neither upgrading nor converting is possible right now, install the last major version that still ships CommonJS, such as node-fetch@2 or chalk@4. Treat it as temporary, because those versions stop getting fixes. On Node.js 18 and later, the built-in fetch removes the need for node-fetch altogether.```
npm install node-fetch@2
```

Checked against the vendor’s docs on November 7, 2026: [Node.js: Modules: Loading ECMAScript modules using require()](https://nodejs.org/api/modules.html); [Node.js: Modules: Packages ("type" and file extensions)](https://nodejs.org/api/packages.html).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**“Cannot use import statement outside a module”**](https://app369.com/fix/node-cannot-use-import-statement-outside-module/) · [**Node.js “Cannot find module”**](https://app369.com/fix/node-cannot-find-module/) · [**Node.js ERR_OSSL_EVP_UNSUPPORTED**](https://app369.com/fix/node-err-ossl-evp-unsupported/) · [**Node.js ERR_INVALID_ARG_TYPE**](https://app369.com/fix/node-err-invalid-arg-type/)

Questions

## **More on this error**

<details>

<summary>**Why does it work locally but fail on the server? **+</summary>

The server or CI usually runs an older Node.js version. Check node -v there, and pin the version in package.json engines, .nvmrc or the host’s settings so every environment uses the same one.

</details>

<details>

<summary>**I use TypeScript. Why does it still call require()? **+</summary>

With "module": "commonjs" in tsconfig.json, TypeScript compiles import into require(). Set "module": "nodenext" (with "type": "module" in package.json) so the output keeps import, or use import() for the ES-only package.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)