Skip to content

Node.js Compatibility

This document assesses how much of the Node.js ecosystem actually runs in bolo, organized into tiers. For the per-module implementation table, see shim-coverage.md.

We classify every package and API into one of four tiers. The tier determines how much (if any) shim support is required.

TierLabelRequires shims?Coverage
T1Web-StandardNo100% today
T2WinterTC MinimumNo (Web APIs)~90% today
T3Node-API via shimsYes~85 to 90%
T4Unsupportedn/aIntentionally absent

Packages written against Web Standards only (fetch, Request, Response, Headers, ReadableStream, WritableStream, AbortController, SubtleCrypto, URL, Blob, FormData, etc.). Zero Node-specific imports.

Coverage: 100%. These run unmodified on native browser APIs with no shims. This is the headline tier: Hono, Elysia, itty-router, and most modern edge-first frameworks land here.

The WinterTC (formerly WinterCG) Minimum Common Web Platform API standard, now formalized as ECMA-429. This tier defines the ~80 mandatory APIs every non-browser JavaScript runtime agrees to provide: fetch, full Streams API, TextEncoder/TextDecoder, URL/URLPattern, CompressionStream, Blob/File, WebCrypto, WebAssembly.*, setTimeout, queueMicrotask, structuredClone, MessageChannel, and the Event/EventTarget family.

Coverage: ~90% via native Web APIs plus node-web-shims. Known gaps:

  • navigator.userAgent is not wired.
  • PromiseRejectionEvent and the onunhandledrejection / onrejectionhandled handlers are not wired.

Closing these gaps is low effort. Once closed, we can publish a compliance audit against the ECMA-429 2025 snapshot and market a measurable percentage. Note the official WinterTC test suite (a WPT subset) is not yet published, so any claim should be hedged as “ECMA-429 2025 snapshot-aligned” until a runnable suite exists.

Packages that import node:* builtins. We provide 28 builtins through two layers: node-web-shims (22 unenv-backed Web API bridges) and node-runtime-shims (6 runtime-backed factories for fs, child_process, process, module, http, net).

Coverage: ~85 to 90% of real-world npm surface after the A1 to A4 work (globals injection, expanded builtins, fs.*Sync on memfs, real http/net streams). The majority of mainstream npm packages that do not depend on raw sockets, native addons, or server-only clustering run here.

Known gaps within T3 (rarely block mainstream packages):

  • http.request() / http.get() / ClientRequest / Agent: our http shim is server-only (ServiceWorker). Client-side HTTP is fetch-only.
  • child_process: spawn/exec work via WASM but stdio is a no-op; execSync / spawnSync / execFile / fork are missing.
  • fs.watch: on() returns a bogus self-closing watcher.
  • process.memoryUsage(): returns zeros.
ModuleStatusNotes
fs (*Sync, async, symlink/readlink/lstat)RealBacked by VfsBus (memfs + OPFS)
http (createServer)RealVirtualServer via sw-sandbox
http (client)Stubfetch only, no ClientRequest
netReal (server)Delegates to createHttpShim
child_processPartialspawn/exec via WASM, no sync variants, stdio no-op
processPartialcwd/hrtime/nextTick/stdout real, exit no-op
modulePartialcreateRequire for builtins + .json only
async_hooks, diagnostics_channel, ttyStubNo-op implementations
Everything else in the 28RealSee shim-coverage.md

Builtins that require capabilities a browser cannot provide safely or at all. Catalogued in PLUGGABLE_BUILTIN_NAMES (packages/node-runtime-shims/src/module-shim.ts:49):

  • cluster, dgram, tls: raw sockets, TLS, clustering. dgram and tls can be back-ended via createLiveShimRegistry; cluster has no browser mapping.
  • dns, http2, inspector, v8, wasi, test, repl, trace_events, domain: not yet provided, most out of scope for a browser runtime.
  • https: aliases the http shim in the browser context.
  • Native addons (NAPI) are pluggable via nativeAddonLoader; otherwise they throw.

The runtime targets workloads that run on Cloudflare Workers, Deno Deploy, or edge runtimes, plus the added advantage of real node:fs and node:stream support. This covers Hono, Express, Fastify, Elysia, the Vercel AI SDK, and most AI agent frameworks. The gaps in T3 rarely block mainstream packages, and T4 is intentionally absent.