Cloudflare · Deployment guide

Cloudflare Pages Node compatibility issues

Short answer

Cloudflare Workers isn't Node — it's a V8 isolate with selective Node compatibility. Most failures are either a missing nodejs_compat flag or a Node-only package that has no Worker build.

Symptoms

  • Build succeeds but runtime throws “Cannot find module” for a Node built-in.
  • Error: “[unenv] X is not implemented yet!” at request time.
  • “__dirname is not defined” after the bundler emits ESM.
  • Works in `wrangler dev` but crashes in production.
  • Imports from sharp, canvas, puppeteer or any *.node binding fail.

Common causes

  • nodejs_compat compatibility flag not enabled in wrangler.toml or Pages settings.
  • Package depends on a native (.node) binding that doesn't ship in Worker bundles.
  • Module uses child_process.spawn — stubbed on Workers, throws at call time.
  • fs.watch / fs.watchFile used somewhere in the import graph.
  • Build pulls in a CommonJS package that expects Node globals (__dirname, __filename).

How DeployDoc checks this

  • Reads wrangler.toml and Pages compatibility flags; flags missing nodejs_compat.
  • Scans dependencies for known Worker-incompatible packages (sharp, puppeteer, etc.).
  • Catches direct imports of child_process / fs.watch / dgram in shipped code.
  • Detects __dirname / __filename references that break under ESM bundling.

Fix it manually

  1. Add compatibility_flags = ["nodejs_compat"] to wrangler.toml.
  2. Set a compatibility_date from at least 2024-09-23 to enable the modern Node shims.
  3. Replace Node-only packages with Worker-compatible alternatives (e.g. sharp@cf-wasm/photon).
  4. Remove imports of child_process, dgram, fs.watch.
  5. Test against a production bundle, not just wrangler dev.

When to run a DeployDoc diagnosis

Whenever a Worker or Pages function works in dev but fails in production, or after adding a new npm dependency.

Related guides