Skip to content
Nilay Kabariya

Entry No.028·Fixes··3 min read

Fix: Dynamic require of "react" / "fs" is not supported

esbuild's ES module output throws this for a require() it left in the bundle. Four fixes tested on Node 24, plus the case only Cloudflare Workers hits.

by Nilay#esbuild#node#esm#cloudflareFIXED

The error, verbatim

Jump to the fix ↓
  throw Error('Dynamic require of "' + x + '" is not supported');
        ^

Error: Dynamic require of "fs" is not supported

# with react marked external:
Error: Dynamic require of "react" is not supported

# on Cloudflare Workers (wrangler dev):
[wrangler:error] Error: Dynamic require of "path" is not supported
✓ Reproduced on Windows 11 Pro

Tested on

esbuild
0.28.2
Node
24.14.0
wrangler
4.139.0
Packages
fs-extra 11.4.1, react 19.3.0
OS
Windows 11 Pro
Contents
  1. The fix01
  2. Why it happens02
  3. On Cloudflare Workers03
  4. What didn’t work04
  5. How this was tested05

The build works, and then the bundle crashes the moment it runs. The name in quotes is the package some CommonJS code tried to require(). It’s usually not your code: a dependency did it.

The fix

Your bundle is an ES module, and ES modules have no require. Pick the fix that fits how the bundle runs:

1. Output CommonJS instead. If the bundle runs in Node and nothing needs it to be ESM, this is the simplest:

npx esbuild src/index.mjs --bundle --platform=node --format=cjs --outfile=dist/out.cjs

2. Keep ESM, and give the bundle a real require (Node only):

npx esbuild src/index.mjs --bundle --platform=node --format=esm --outfile=dist/out.mjs --banner:js="import { createRequire } from 'module'; const require = createRequire(import.meta.url);"

In a build script, the same banner goes in banner: { js: "..." }.

3. If the require is inside a package, don’t bundle node_modules. Node then loads each package itself, CommonJS included:

npx esbuild src/index.mjs --bundle --platform=node --format=esm --packages=external --outfile=dist/out.mjs

4. If the name is a package you marked external (like --external:react), either stop marking it external so esbuild bundles it, or use fix 2.

Why it happens

When esbuild bundles a CommonJS file into ES module output, it can’t turn every require() into an import. For the ones it leaves, it writes this stub at the top of your bundle:

var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
  if (typeof require !== "undefined") return require.apply(this, arguments);
  throw Error('Dynamic require of "' + x + '" is not supported');
});

It calls the real require if one exists, and throws if not. In an ES module there isn’t one. That’s why fix 2 works: the banner defines require before the stub runs.

On Cloudflare Workers

Workers behave differently, and it changes the fix. Through wrangler’s own bundler, plain require() calls worked in a CommonJS file, with or without nodejs_compat:

require() in a CommonJS dependency Result on Workers
require('fs') worked
require('node:crypto') worked
require('buffer') worked
require(name), with the name built at runtime Dynamic require of "path" is not supported

The last one failed with nodejs_compat on as well. The bundler can only handle a require whose name it can read at build time. Change require(name) to the literal require('path'), and the same Worker returned 200.

What didn’t work

How this was tested

A small project with an ES module entry importing a local CommonJS file that calls require('fs'), a second entry using fs-extra 11.4.1 from npm, and a CommonJS file requiring react 19.3.0 with react marked external. Each was bundled with esbuild 0.28.2 in every variant above and run with Node 24.14.0. The Workers table comes from wrangler dev 4.139.0 with compatibility_date 2026-09-01, run once without and once with nodejs_compat.

— N.K., end of entry No.028

Useful? Pass it on:Post on XFollow @EmotionalMatter

Related entries

  1. No.025

    Fix: TypeScript enum is not supported in strip-only mode

    Node's ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX for enum, parameter properties, namespace, export = and import =. Two ways to run it unchanged, both tested.

    > enum Color { Red, Green }

    FIXED3 min
  2. No.015

    Fix: This syntax is not allowed when 'erasableSyntaxOnly' is enabled

    TS1294: TypeScript rejects your enum, namespace or constructor shorthand. Why new projects turn this on, what each piece becomes, and when to switch it off.

    > src/a.ts(1,6): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.

    FIXED3 min
  3. No.014

    Fix: ERR_MODULE_NOT_FOUND Cannot find module in ES modules

    Node can't find a file that is clearly there. What ES modules changed about relative imports, why TypeScript path aliases break at runtime, and what to change.

    > node:internal/modules/esm/resolve:275

    FIXED2 min

Post card · Newsletter

Get the next fix in your inbox.

One short email when a new entry is published. No spam, never shared, and you can leave any time.

— Nilay

or follow by RSSor on X

By subscribing you agree to the privacy note. One click to leave.

tip: paste the exact error text