If a package works in Node.js but doesn’t work in Bun, that’s a bug in Bun. Open an issue and it will be fixed.
Module system
Bun supports both CommonJS and ES modules. You can userequire() and import in the same project, and Bun handles the interop automatically.
require() is fully implemented, including require.main, require.cache, and require.resolve.
npm packages
npm packages install and run with Bun without any changes. Bun readspackage.json, resolves dependencies from node_modules, and handles both CJS and ESM packages.
Node.js globals
Bun exposes the same globals Node.js does. These are available without any imports.| Global | Status | Notes |
|---|---|---|
process | Mostly implemented | process.binding partially implemented; process.title is a no-op on macOS and Linux |
Buffer | Fully implemented | |
__dirname | Fully implemented | |
__filename | Fully implemented | |
global | Fully implemented | Object containing all globals in the global namespace |
globalThis | Fully implemented | Aliases to global |
module | Fully implemented | |
exports | Fully implemented | |
require() | Fully implemented |
process
process is available globally without importing node:process. Most properties and methods are implemented.
process.binding (used by some packages to access Node.js internals) is partially implemented. getActiveResourcesInfo, setActiveResourcesInfo, getActiveResources, and setSourceMapsEnabled are stubs. process.loadEnvFile and process.getBuiltinModule are not yet implemented.Buffer
Buffer is a global subclass of Uint8Array, identical to Node.js.
Built-in modules
Fully implemented
These modules pass 90–100% of Node.js’s own test suite.node:assert
Fully implemented.
node:buffer
Fully implemented.
node:console
Fully implemented.
node:dgram
Fully implemented. Over 90% of Node.js’s test suite passes.
node:diagnostics_channel
Fully implemented.
node:dns
Fully implemented. Over 90% of Node.js’s test suite passes.
node:events
Fully implemented. 100% of Node.js’s test suite passes.
EventEmitterAsyncResource uses AsyncResource underneath.node:fs
Fully implemented. 92% of Node.js’s test suite passes.
node:http
Fully implemented. Outgoing client request body is currently buffered instead of streamed.
node:https
APIs are implemented;
Agent is not always used yet.node:net
Fully implemented.
node:os
Fully implemented. 100% of Node.js’s test suite passes.
node:path
Fully implemented. 100% of Node.js’s test suite passes.
node:querystring
Fully implemented. 100% of Node.js’s test suite passes.
node:readline
Fully implemented.
node:stream
Fully implemented.
node:string_decoder
Fully implemented. 100% of Node.js’s test suite passes.
node:timers
Fully implemented. Prefer the global
setTimeout and setInterval directly.node:tty
Fully implemented.
node:url
Fully implemented.
node:zlib
Fully implemented. 98% of Node.js’s test suite passes.
Partially implemented
These modules work for most use cases but have some gaps compared to Node.js.| Module | Status |
|---|---|
node:async_hooks | AsyncLocalStorage and AsyncResource are implemented. V8 promise hooks are not called. |
node:child_process | Missing proc.gid, proc.uid. Stream class not exported. IPC cannot send socket handles. Node.js ↔ Bun IPC works with JSON serialization. |
node:cluster | Handles and file descriptors cannot be passed between workers. Load-balancing HTTP across processes is only supported on Linux (via SO_REUSEPORT). |
node:crypto | Missing secureHeapUsed, setEngine, setFips. |
node:domain | Missing Domain, active. |
node:http2 | Client and server implemented (95.25% of gRPC’s test suite passes). Missing options.allowHTTP1, options.enableConnectProtocol, ALTSVC extension, and http2stream.pushStream. |
node:inspector | Profiler API is supported. Other inspector APIs are not yet implemented. |
node:module | Missing syncBuiltinESMExports, Module#load(). module.register is not implemented — use Bun.plugin instead. |
node:perf_hooks | APIs implemented but Node.js test suite does not pass yet. |
node:process | See process global. |
node:test | Partially implemented. Missing mocks, snapshots, timers. Use bun:test instead. |
node:tls | Missing tls.createSecurePair. |
node:util | Missing getCallSite, getCallSites, getSystemErrorMap, getSystemErrorMessage, transferableAbortSignal, transferableAbortController. |
node:v8 | writeHeapSnapshot and getHeapSnapshot implemented. serialize and deserialize use JavaScriptCore’s wire format, not V8’s. Use bun:jsc for profiling. |
node:vm | Core functionality and ES modules are implemented. Missing vm.measureMemory and some cachedData functionality. |
node:wasi | Partially implemented. |
node:worker_threads | Worker doesn’t support stdin, stdout, stderr, trackedUnmanagedFds, resourceLimits. Missing markAsUntransferable, moveMessagePortToContext. |
Not yet implemented
| Module | Notes |
|---|---|
node:repl | Not implemented. |
node:sqlite | Not implemented. Use bun:sqlite instead. |
node:trace_events | Not implemented. |
N-API (native addons)
Bun implements approximately 95% of the Node-API (N-API) interface. Most existing native addons built for Node.js work with Bun out of the box.For building new native addons, writing a Node-API (NAPI) module is the most stable way to interact with native code from Bun.
bun:ffi is available but experimental.JavaScriptCore vs V8
Bun uses JavaScriptCore (JSC), the engine from WebKit, rather than V8. This means:- Standard JavaScript behavior is identical — all ECMAScript-compliant code runs the same way.
- V8-specific internal APIs (such as
v8.serializewire format) may differ. node:v8’sserializeanddeserializeuse JSC’s wire format, not V8’s.- The
--inspectprotocol is compatible but Bun’s debugger integration is distinct.