> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/oven-sh/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js compatibility

> Bun aims to be a drop-in replacement for Node.js. This page tracks compatibility with Node.js built-in modules, globals, and native addons.

Bun is designed to be a drop-in replacement for Node.js. Popular frameworks like Next.js, Express, and millions of npm packages intended for Node.js work with Bun without changes. To validate this, Bun runs thousands of tests from Node.js's own test suite before every release.

<Note>
  If a package works in Node.js but doesn't work in Bun, that's a bug in Bun. [Open an issue](https://bun.com/issues) and it will be fixed.
</Note>

The compatibility information on this page reflects Bun's support for **Node.js v23** APIs.

## Module system

Bun supports both CommonJS and ES modules. You can use `require()` and `import` in the same project, and Bun handles the interop automatically.

<CodeGroup>
  ```typescript esm.ts theme={null}
  import { readFileSync } from "node:fs";
  const contents = readFileSync("./file.txt", "utf8");
  ```

  ```javascript cjs.js theme={null}
  const { readFileSync } = require("node:fs");
  const contents = readFileSync("./file.txt", "utf8");
  ```
</CodeGroup>

`require()` is fully implemented, including [`require.main`](https://nodejs.org/api/modules.html#requiremain), [`require.cache`](https://nodejs.org/api/modules.html#requirecache), and [`require.resolve`](https://nodejs.org/api/modules.html#requireresolverequest-options).

## npm packages

npm packages install and run with Bun without any changes. Bun reads `package.json`, resolves dependencies from `node_modules`, and handles both CJS and ESM packages.

```bash theme={null}
bun install        # reads package.json, installs deps
bun run index.ts   # runs your code with full npm resolution
```

## 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.

```typescript theme={null}
console.log(process.version);     // e.g. "v23.0.0"
console.log(process.platform);    // "linux", "darwin", "win32"
console.log(process.env.HOME);    // reads environment variables
process.exit(0);
```

<Note>
  `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.
</Note>

### `Buffer`

`Buffer` is a global subclass of `Uint8Array`, identical to Node.js.

```typescript theme={null}
const buf = Buffer.from("hello world", "utf8");
console.log(buf.toString("hex"));
console.log(buf.toString("base64"));
```

## Built-in modules

### Fully implemented

These modules pass 90–100% of Node.js's own test suite.

<CardGroup cols={3}>
  <Card title="node:assert" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:buffer" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:console" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:dgram" icon="check">
    Fully implemented. Over 90% of Node.js's test suite passes.
  </Card>

  <Card title="node:diagnostics_channel" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:dns" icon="check">
    Fully implemented. Over 90% of Node.js's test suite passes.
  </Card>

  <Card title="node:events" icon="check">
    Fully implemented. 100% of Node.js's test suite passes. `EventEmitterAsyncResource` uses `AsyncResource` underneath.
  </Card>

  <Card title="node:fs" icon="check">
    Fully implemented. 92% of Node.js's test suite passes.
  </Card>

  <Card title="node:http" icon="check">
    Fully implemented. Outgoing client request body is currently buffered instead of streamed.
  </Card>

  <Card title="node:https" icon="check">
    APIs are implemented; `Agent` is not always used yet.
  </Card>

  <Card title="node:net" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:os" icon="check">
    Fully implemented. 100% of Node.js's test suite passes.
  </Card>

  <Card title="node:path" icon="check">
    Fully implemented. 100% of Node.js's test suite passes.
  </Card>

  <Card title="node:querystring" icon="check">
    Fully implemented. 100% of Node.js's test suite passes.
  </Card>

  <Card title="node:readline" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:stream" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:string_decoder" icon="check">
    Fully implemented. 100% of Node.js's test suite passes.
  </Card>

  <Card title="node:timers" icon="check">
    Fully implemented. Prefer the global `setTimeout` and `setInterval` directly.
  </Card>

  <Card title="node:tty" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:url" icon="check">
    Fully implemented.
  </Card>

  <Card title="node:zlib" icon="check">
    Fully implemented. 98% of Node.js's test suite passes.
  </Card>
</CardGroup>

### 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`](/runtime/plugins) instead.                                             |
| `node:perf_hooks`     | APIs implemented but Node.js test suite does not pass yet.                                                                                                                         |
| `node:process`        | See [`process`](#process) global.                                                                                                                                                  |
| `node:test`           | Partially implemented. Missing mocks, snapshots, timers. Use [`bun:test`](/test/overview) 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`](/runtime/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.

```javascript theme={null}
// .node files can be required directly
const napi = require("./my-node-module.node");

// Or loaded via process.dlopen
let mod = { exports: {} };
process.dlopen(mod, "./my-node-module.node");
```

<Note>
  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.
</Note>

## 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.serialize` wire format) may differ.
* `node:v8`'s `serialize` and `deserialize` use JSC's wire format, not V8's.
* The `--inspect` protocol is compatible but Bun's debugger integration is distinct.

For most application code and npm packages, the difference is invisible. Packages that rely on V8 internals directly (e.g. some profiling tools) may require updates.
