Skip to content

Cloudflare Workers Compatibility Checker for npm

Check which npm packages run on Cloudflare Workers, which need nodejs_compat and which will not run, then copy the compatibility_date and flags.

  • Reads the npm registry
  • Reads jsDelivr file lists
  • Reads jsDelivr

Checked

01Tool

Tool

Required
Optional

Paste a package.json or a list of package names to see which run on Cloudflare Workers as they are, which need Node.js compatibility, and which will not run, with the wrangler.jsonc settings the result needs.

What you paste stays in this tab until you press Check packages. Then the page sends the name and version of each package to registry.npmjs.org, and asks jsDelivr for its file list (data.jsdelivr.com) and the entry files it reads (cdn.jsdelivr.net). Nothing is stored, and your package.json never goes in the address.

What compatibility_date and flags do

compatibility_date
Picks the version of the Workers runtime your Worker runs on: every change up to that day applies. Cloudflare supports old dates forever and recommends today's date for a new project.
compatibility_flags
Turn a single change on before its default date, or off after it.
nodejs_compat
Turns on the Node.js APIs built into the runtime, plus Wrangler's polyfills for the rest. From 2026-08-04, the date turns it on and the flag does nothing.
enable_nodejs_…_module
Turns on one Node.js module before the date it ships by default, such as enable_nodejs_fs_module.
no_nodejs_compat
From 2026-08-04, turning Node.js compatibility off takes both no_nodejs_compat and no_nodejs_compat_v2.

02Guide

How it works

How the checker reads a package

Nothing leaves the page until you press Check packages. Then, for each package, the checker asks the npm registry for the newest version your range allows, the same one a fresh install picks, and asks jsDelivr for that version's file list.

From the file list and the package's manifest it finds the file Wrangler would bundle. Wrangler builds with esbuild and sets the workerd, worker and browser conditions, so in a package's exports the checker takes the first key among those, import and default, in the order the package lists them. A package without exports falls back to its browser, module and main fields, in that order, and a browser map that swaps a file or switches a module off is applied too.

It then reads that entry file and the files it imports inside the same package, up to a cap, and collects every import, export … from, require() and import() with a fixed string. A require inside a try block or a dynamic import() counts as optional, because a package that guards a Node.js import usually has a fallback.

Before reading any code, it looks for signs of native code: a .node file or binding.gyp in the package, an install script that runs node-gyp or prebuild-install, a dependency on a native loader such as node-gyp-build, a set of per-platform binary packages in optionalDependencies, or an os or cpu list that limits where it installs.

What the five results mean

Runs as is. The entry files import no Node.js built-in and nothing native turned up. Many packages written for browsers or for several runtimes land here, and some ship a build just for Workers under the workerd or worker condition.

Needs Node.js compatibility. The package imports at least one Node.js module. The result says which ones, in which file, and the first compatibility date on which all of them work.

Loads, some calls fail. The package also imports a module that Workers ship only as a stub, such as node:child_process. It loads, but whatever calls into that module throws. That can be one transport you never use, as with nodemailer's sendmail, or the whole point of the package, as with execa.

Will not run. The package needs native code, or drives a browser on the same machine as Puppeteer and Playwright do, so no compatibility date or flag will make it work. The Workers option beside it points to the Cloudflare product that covers the same job where one is well known.

Could not tell. npm does not know the package or version, the version is local such as workspace: or file:, the package has no entry file to import, its entry file is too large to read here, or it is a Nuxt module.

The compatibility date and nodejs_compat

compatibility_date pins the version of the Workers runtime your Worker runs on, and compatibility_flags turn single changes on or off around it. Node.js support is one of those changes, and several Node.js modules arrived on later dates, so the checker works out the earliest date that covers every module the packages import.

For a new project, the settings use today's date, which already turns Node.js compatibility on, so they need no flag. A project that stays on a date from before that default needs the flag, like this:

{
  "compatibility_date": "2026-03-17",
  "compatibility_flags": ["nodejs_compat"],
}

If you keep an older date, type it in. The checker keeps it when it is new enough, adds nodejs_compat when the date needs it, and otherwise says which date to move to, or which enable_nodejs_…_module flags would keep your date working instead.

Static detection has limits

The checker never runs the code. It sees imports written as plain strings, not modules picked at runtime, Node.js globals such as Buffer or __dirname used without an import, or which branch of a package your app reaches. It reads only the packages you list, so a dependency of a dependency that needs Node.js stays invisible unless you add it by name. It also stops after a fixed number of files per package and says so.

Frameworks and build tools such as Nuxt, Vite and Wrangler run at build time, so the checker skips them along with type packages. A framework that targets Workers is judged by what its build puts in the bundle, not by its package entry. A Nuxt module, such as @nuxt/ui, is the same case: its entry runs in the Nuxt build and imports Node.js freely, while the runtime code it adds is bundled by Nitro, so it reads as could not tell rather than as a false alarm.

03Rates

The numbers it uses

Compatibility dates
ItemDateSource
nodejs_compat on by default 2026-08-04developers.cloudflare.com
nodejs_compat includes Wrangler's polyfills 2024-09-23developers.cloudflare.com
node:http and node:https clients 2025-08-15developers.cloudflare.com
A Worker uploaded through the API without a date 2021-11-02developers.cloudflare.com
Node.js modules on Workers
ItemOn WorkersSource
node:assert Supporteddevelopers.cloudflare.com
node:async_hooks Only AsyncLocalStorage and AsyncResource; the rest of async_hooks is missing.Partly supporteddevelopers.cloudflare.com
node:buffer Supporteddevelopers.cloudflare.com
node:child_process Earlier: enable_nodejs_child_process_moduleStub only, from 2026-03-17developers.cloudflare.com
node:cluster Earlier: enable_nodejs_cluster_moduleStub only, from 2025-12-04developers.cloudflare.com
node:console Earlier: enable_nodejs_console_modulePartly supported, from 2025-09-21developers.cloudflare.com
node:constants Polyfilled by Wranglergithub.com
node:crypto All of it except argon2, DSA and DH key pairs, and the ed448 and x448 curves.Supporteddevelopers.cloudflare.com
node:dgram Earlier: enable_nodejs_dgram_moduleStub only, from 2026-01-29developers.cloudflare.com
node:diagnostics_channel Supporteddevelopers.cloudflare.com
node:dns lookup, lookupService and resolve throw; the rest resolves over DNS over HTTPS.Partly supporteddevelopers.cloudflare.com
node:domain Earlier: enable_nodejs_domain_moduleStub only, from 2025-12-04developers.cloudflare.com
node:events Supporteddevelopers.cloudflare.com
node:fs A virtual file system: your bundle's modules, read-only, and a /tmp that lasts one request. Earlier: enable_nodejs_fs_moduleSupported, from 2025-09-15developers.cloudflare.com
node:http Client APIs from 2025-08-15, http.createServer from 2025-09-01. Earlier: enable_nodejs_http_modules, enable_nodejs_http_server_modulesSupported, from 2025-09-01developers.cloudflare.com
node:http2 Earlier: enable_nodejs_http2_moduleStub only, from 2025-09-01developers.cloudflare.com
node:https Client APIs from 2025-08-15, http.createServer from 2025-09-01. Earlier: enable_nodejs_http_modules, enable_nodejs_http_server_modulesSupported, from 2025-09-01developers.cloudflare.com
node:inspector Earlier: enable_nodejs_inspector_moduleStub only, from 2026-01-29developers.cloudflare.com
node:module Partly supporteddevelopers.cloudflare.com
node:net Sockets connect out; net.Server is not supported.Supporteddevelopers.cloudflare.com
node:os Earlier: enable_nodejs_os_modulePartly supported, from 2025-09-15developers.cloudflare.com
node:path Supporteddevelopers.cloudflare.com
node:perf_hooks Earlier: enable_nodejs_perf_hooks_modulePartly supported, from 2026-03-17developers.cloudflare.com
node:process The full process object from 2025-09-15; before it, only nextTick, env, exit, getBuiltinModule, platform and features. Earlier: enable_nodejs_process_v2Supported, from 2025-09-15developers.cloudflare.com
node:punycode Earlier: enable_nodejs_punycode_moduleSupported, from 2025-12-04developers.cloudflare.com
node:querystring Supporteddevelopers.cloudflare.com
node:readline Earlier: enable_nodejs_readline_moduleStub only, from 2026-03-17developers.cloudflare.com
node:repl Earlier: enable_nodejs_repl_moduleStub only, from 2026-03-17developers.cloudflare.com
node:sqlite Earlier: enable_nodejs_sqlite_moduleStub only, from 2026-01-29developers.cloudflare.com
node:stream Supporteddevelopers.cloudflare.com
node:string_decoder Supporteddevelopers.cloudflare.com
node:sys Polyfilled by Wranglergithub.com
node:test Partly supporteddevelopers.cloudflare.com
node:timers Supporteddevelopers.cloudflare.com
node:tls Only connect, TLSSocket, checkServerIdentity and createSecureContext; servers are not supported.Partly supporteddevelopers.cloudflare.com
node:trace_events Earlier: enable_nodejs_trace_events_moduleStub only, from 2025-12-04developers.cloudflare.com
node:tty Earlier: enable_nodejs_tty_moduleStub only, from 2026-03-17developers.cloudflare.com
node:url Supporteddevelopers.cloudflare.com
node:util Supporteddevelopers.cloudflare.com
node:v8 Earlier: enable_nodejs_v8_moduleStub only, from 2026-03-17developers.cloudflare.com
node:vm Earlier: enable_nodejs_vm_moduleStub only, from 2025-10-01developers.cloudflare.com
node:wasi Earlier: enable_nodejs_wasi_moduleStub only, from 2025-12-04developers.cloudflare.com
node:worker_threads Earlier: enable_nodejs_worker_threads_moduleStub only, from 2026-03-17developers.cloudflare.com
node:zlib Earlier: nodejs_zlibSupported, from 2024-09-23developers.cloudflare.com
node:_stream_wrap Earlier: enable_nodejs_stream_wrap_moduleStub only, from 2026-01-29developers.cloudflare.com

04Questions

Questions

Do I still need the nodejs_compat flag?
Only on a compatibility date before the one the checker names. From that date, Workers turn on nodejs_compat and nodejs_compat_v2 by default and ignore the flags, so you can leave them in or take them out. On an earlier date, add nodejs_compat to compatibility_flags in wrangler.jsonc.
Which compatibility date should I use?
Today's, for a new project. Cloudflare recommends it and supports old dates forever, so you never have to move it. When you do move it, read the compatibility flags page for what changed in between, because some of those changes are backwards-incompatible on purpose.
Which Node.js modules work on Cloudflare Workers?
Most of what a server library reaches for, including buffer, crypto, events, fs, http, net, path, process, stream, url, util and zlib, some of them only from a given compatibility date. dns, os, tls and a few others work in part. child_process, worker_threads, vm and some others exist only as stubs that load but do not work. The table on this page lists every module.
Why will a package with native code not run on Workers?
Workers run your code in V8 isolates, not in a Node.js process, so a compiled .node addon has nothing to load into. sharp, bcrypt and better-sqlite3 are the usual cases, and each has a Workers route instead, such as the Images binding, password hashing through Web Crypto, and D1.
Does a package that imports child_process break my Worker?
Not by loading. With Node.js compatibility on, child_process is a stub, so the import succeeds and only calls into it fail. A library that spawns processes only in its command-line tool can work fine, while a package built to run commands, such as execa, cannot.
How accurate is the check?
It is static and heuristic. It resolves each package the way Wrangler does and reads its entry files, but it does not run them, follow the packages they depend on, see Node.js globals such as Buffer used without an import, or know which code paths your app calls. Treat a clean result as a good sign and confirm it with wrangler dev.

05Sources

Sources

Every fact on this page was read from these pages on .

  1. Cloudflare docs, Node.js compatibilitydevelopers.cloudflare.com/workers/runtime-apis/nodejs/
  2. Cloudflare docs, Compatibility flagsdevelopers.cloudflare.com/workers/configuration/compatibility-flags/
  3. Cloudflare docs, Compatibility datesdevelopers.cloudflare.com/workers/configuration/compatibility-dates/
  4. Cloudflare docs, Wrangler bundlingdevelopers.cloudflare.com/workers/wrangler/bundling/
  5. Wrangler source, build conditionsgithub.com/cloudflare/workers-sdk/blob/main/packages/wrangler/src/deployment-bundle/bundle.ts
  6. esbuild docs, conditions and main fieldsesbuild.github.io/api/#conditions
  7. Node.js docs, conditional exportsnodejs.org/api/packages.html#conditional-exports
  8. Cloudflare docs, How Workers worksdevelopers.cloudflare.com/workers/reference/how-workers-works/
  9. Cloudflare docs, node:fsdevelopers.cloudflare.com/workers/runtime-apis/nodejs/fs/
  10. Cloudflare docs, node:cryptodevelopers.cloudflare.com/workers/runtime-apis/nodejs/crypto/
  11. Cloudflare docs, node:dnsdevelopers.cloudflare.com/workers/runtime-apis/nodejs/dns/
  12. Cloudflare docs, node:netdevelopers.cloudflare.com/workers/runtime-apis/nodejs/net/
  13. Cloudflare docs, node:tlsdevelopers.cloudflare.com/workers/runtime-apis/nodejs/tls/
  14. Cloudflare docs, AsyncLocalStoragedevelopers.cloudflare.com/workers/runtime-apis/nodejs/asynclocalstorage/
  15. unenv, the Node.js polyfills Wrangler usesgithub.com/unjs/unenv/tree/main/src/runtime/node
  16. Cloudflare docs, Images bindingdevelopers.cloudflare.com/images/optimization/binding/
  17. Cloudflare docs, D1developers.cloudflare.com/d1/
  18. Cloudflare docs, Web Cryptodevelopers.cloudflare.com/workers/runtime-apis/web-crypto/
  19. Cloudflare docs, Browser Run with Puppeteerdevelopers.cloudflare.com/browser-run/puppeteer/
  20. Cloudflare docs, Browser Run with Playwrightdevelopers.cloudflare.com/browser-run/playwright/
  21. Cloudflare docs, Cron Triggersdevelopers.cloudflare.com/workers/configuration/cron-triggers/
  22. Cloudflare docs, Queuesdevelopers.cloudflare.com/queues/
  23. Cloudflare docs, WebSocketsdevelopers.cloudflare.com/workers/runtime-apis/websockets/
  24. Cloudflare docs, Fetchdevelopers.cloudflare.com/workers/runtime-apis/fetch/

Found something out of date? Tell us.

Nuxter

Building a SaaS on Nuxt?

Nuxter is a Nuxt 4 starter kit built for Cloudflare Workers, with Postgres through Hyperdrive, sessions, payments, email and queued jobs already running on the runtime.

See what Nuxter includesFrom $249, one-time.