new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Runtime · all subjects

node compatibility

35 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Bun node:cluster module support

Bun implements the node:cluster module. The reusePort option is a faster but more limited alternative to the node:cluster module for creating HTTP server clusters.

Bun disables .env loading when invoked as node

When invoked as node (via bun --bun, bunx --bun, or a node symlink pointing at Bun), Bun disables automatic .env loading to match Node.js behavior. This allows tools with their own mode-aware .env resolution, such as Vite's loadEnv, to pick the correct .env.{mode} file. Bun still honors explicit --env-file arguments.

Node.js fs.glob() compatibility

Bun implements Node.js fs.glob(), fs.globSync(), and fs.promises.glob() functions. These can be imported from 'node:fs'. All three support array of patterns as the first argument and the exclude option to filter results.

fs.glob() exclude option

The fs.glob() and related functions support an exclude option to filter out matched results. Example: promises.glob("**/*", { exclude: ["node_modules/**", "**/*.test.*"] }) excludes files matching those patterns.

fs.glob() multiple patterns example

Example code: import { promises } from "node:fs"; const files = await Array.fromAsync(promises.glob(["**/*.ts", "**/*.js"])); This uses fs.promises.glob() with an array of multiple patterns to match both TypeScript and JavaScript files.

Node crypto compatibility

Bun implements the createHash and createHmac functions from node:crypto module in addition to the Bun-native hashing APIs.

node:dgram UDP socket implementation

node:dgram is fully implemented in Bun. 99% of Node.js's test suite passes. addMembership() does not implicitly bind an unbound socket; you must call bind() first.

node:child_process IPC limitations

node:child_process IPC can send net.Socket, net.Server and dgram.Socket handles (including to and from Node.js processes), but not http server sockets. serialization: 'advanced' only works between Bun processes, so use JSON serialization for Node.js ↔ Bun IPC. Missing subprocess.channel.ref()/unref(). You cannot pass a child's stdout/stderr as another child's stdio, and spawnSync does not return extra stdio pipes in output.

node:cluster implementation

node:cluster: net and dgram servers in workers are shared through the primary as in Node.js (SCHED_RR and SCHED_NONE), and handles can be passed with worker.send(). node:http/node:https servers in workers each bind their own socket instead, so load-balancing HTTP requests across processes is only supported on Linux (through SO_REUSEPORT). Otherwise, implemented but not battle-tested.

process global partially implemented

process global is mostly implemented. process.binding (internal Node.js bindings) is partially implemented: buffer, config, constants, fs, natives, tty_wrap, util and uv are available, the rest throw. Setting process.title is a no-op on macOS & Linux. getActiveResourcesInfo(), _getActiveHandles() and _getActiveRequests() always return an empty array, setSourceMapsEnabled() is a no-op, and process.report.writeReport() writes nothing. Missing sourceMapsEnabled and addUncaughtExceptionCaptureCallback.

Bun test node:test implementation status

node:test is partially implemented. The in-process API works when test files run under bun test: tests, suites, subtests, hooks, t.plan(), t.assert, assert.register(), t.waitFor(), getTestContext(), expectFailure, and t.mock (function/method/getter/setter/property mocks and mock timers). run() requires an explicit files list and runs each file in a bun test child process. Most options throw ERR_NOT_IMPLEMENTED. Missing node:test/reporters, snapshot testing, mock.module(), t.runOnly(), code coverage, --test-only, test-level signal abort, and Node's --test CLI runner mode. test.only() / {only: true} are accepted but do not filter. concurrency is validated but subtests always run serially.

node:trace_events fully implemented

node:trace_events is fully implemented. createTracing(), getEnabledCategories() and the --trace-events-enabled, --trace-event-categories and --trace-event-file-pattern flags are supported. Bun writes the trace at exit. Some categories record less than in Node.js. For example, node.async_hooks only records timers, and the v8 category is a placeholder, since JavaScriptCore has no V8 GC or compile events.

node:console differences

node:console is fully implemented. Bun writes console output directly to the stdout/stderr file descriptors and formats it with its own inspector. As a result, replacing process.stdout.write does not capture the output, and object layout differs from util.inspect. console.trace() writes to stdout and console.time*() to stderr.

node:async_hooks implementation

node:async_hooks: AsyncLocalStorage and AsyncResource are implemented. createHook, executionAsyncId, triggerAsyncId and executionAsyncResource are stubs: Bun does not invoke hooks, apart from init for process.nextTick, and async ids are always 0. Node.js strongly discourages these APIs in favor of AsyncLocalStorage. Bun does not propagate AsyncLocalStorage context into MessagePort, BroadcastChannel or Worker events.

node:path matchesGlob semantics

node:path is fully implemented. matchesGlob() uses Bun.Glob semantics rather than minimatch (* matches dotfiles, no extglobs). path.win32 differs from Node in a few edge cases involving device paths and reserved names.

node:stream isReadable limitations

node:stream is fully implemented. isReadable, isWritable, isErrored and Readable.isDisturbed only understand Node.js streams, not web streams.

node:diagnostics_channel partial implementation

node:diagnostics_channel: channel(), subscribe(), tracingChannel() and the http client, http2 and dgram built-in channels are implemented. Missing boundedChannel() and the http.server.*, net, module, console, child_process and worker_threads built-in channels. Subscribers do not keep a Channel alive, so hold a reference to it.

node:dns fully implemented

node:dns is fully implemented. Missing resolveTlsa. Bun ignores the Resolver maxTimeout option, and the callback-style Resolver class cannot be subclassed (dns.promises.Resolver can).

node:util limitations

node:util is missing diff, transferableAbortSignal and transferableAbortController. debuglog() ignores its callback argument and the returned function has no enabled property.

node:v8 limitations

node:v8: writeHeapSnapshot, getHeapSnapshot, getHeapStatistics, getHeapSpaceStatistics, GCProfiler and startupSnapshot are implemented. The heap statistics describe JavaScriptCore's single heap, and setFlagsFromString ignores the flags it is given. serialize and deserialize use JavaScriptCore's wire format instead of V8's. Missing queryObjects, startCpuProfile, startHeapProfile, Serializer/Deserializer, takeCoverage/stopCoverage and promiseHooks. For profiling, use bun:jsc instead.

node:wasi partial implementation

node:wasi is partially implemented. WASI supports args, env, preopens, wasiImport and start(), and bun ./program.wasm runs a WASI command directly. Missing getImportObject() (use wasiImport), initialize() and the sock_accept import. Bun ignores the version, returnOnExit, stdin, stdout and stderr options, so proc_exit exits the Bun process.

node:inspector partial implementation

node:inspector is partially implemented. Session supports the Profiler domain (including precise coverage), Runtime.enable and NodeTracing, from both node:inspector and node:inspector/promises. Other Session commands such as Runtime.evaluate and the HeapProfiler domain are not implemented. open(), url(), close() and waitForDebugger() are implemented. open() serves the Debugger and Runtime domains and throws in workers. Missing Network.

node:perf_hooks partial implementation

node:perf_hooks: monitorEventLoopDelay(), createHistogram(), timerify() and PerformanceObserver (mark, measure, function, net, http and http2 entries) are implemented. Bun never emits gc, dns or resource entries. eventLoopUtilization() always returns zeros, and performance.nodeTiming holds placeholder values. The Node-specific additions to the global performance object only appear once node:perf_hooks has been imported.

Bun achieves high Node.js compatibility

Every day, Bun gets closer to 100% Node.js API compatibility. Popular frameworks like Next.js, Express, and millions of npm packages intended for Node.js work with Bun. Bun runs thousands of tests from Node.js' test suite before every release. If a package works in Node.js but doesn't work in Bun, it is considered a bug in Bun. Bun's compatibility is tested with Node.js v26.

node:domain limitations

node:domain is missing Domain members. A domain only catches errors thrown synchronously inside run()/bind() or emitted by emitters passed to add(). Bun does not route errors from timers, process.nextTick, promises and other async callbacks to the domain.

node:module limitations

node:module is missing Module#load(), registerHooks, findPackageJSON, stripTypeScriptTypes, getSourceMapsSupport/setSourceMapsSupport. Overriding require.cache, require.extensions and module._resolveFilename is supported. syncBuiltinESMExports, module._load, module._pathCache and module.register are no-ops (use Bun.plugin instead). findSourceMap always returns undefined.

node:os implementation details

node:os is fully implemented. userInfo() reads username, shell and homedir from the environment (USER, SHELL, HOME) rather than the passwd database. machine() returns 'arm64' instead of 'aarch64' on Linux arm64.

node:repl mostly implemented

node:repl is mostly implemented. bun --interactive starts a Node.js-compatible REPL. The REPL does not show result previews (they need V8's inspector-based side-effect-free eval). Tab-completion skips let/const/class bindings, and some V8-specific error-message and stack-frame wording differs.

node:assert deepEqual semantics

node:assert is fully implemented. Legacy-mode deepEqual uses Bun.deepEquals semantics rather than Node's loose == comparison, and function-valued or printf-style message arguments are not formatted.

PerformanceObserver limitations

PerformanceObserver: Observing mark and measure entries works. Bun only delivers Node-only entry types (function, http, net, ...) to the node:perf_hooks PerformanceObserver, and never emits gc, dns or resource entries.

PerformanceResourceTiming not implemented

PerformanceResourceTiming: The class exists, but no entries are ever created: fetch() does not record resource timing and performance.markResourceTiming() is a no-op.

performance global partial implementation

performance global: now(), timeOrigin, mark(), measure() and getEntries() are implemented. The Node.js additions (eventLoopUtilization(), nodeTiming, timerify()) only exist once node:perf_hooks has been loaded. eventLoopUtilization() always returns zeros and nodeTiming holds placeholder values.

Node streams module compatibility

Bun implements the node:stream module, including Readable, Writable, and Duplex streams for compatibility with Node.js code.

REPL Node.js globals

The REPL makes available Node.js globals including require, module, __dirname, and __filename, resolved relative to the current working directory.

node:dns.lookup always uses system backend

node:dns.lookup() always uses the "system" backend to match Node.js behavior. The node:dns.resolve*() functions use c-ares, as they do in Node.js.

Give your agent this brain