Bun Knowledge Patch
Use this skill for Bun runtime, package-manager, bundler, test-runner, server,
database, and Node.js-compatibility work. Establish the project's actual Bun
release before applying version-attributed guidance from the references.
Read only the references relevant to the task. When project code, tests, or
observed behavior disagree with this guidance, treat the project as decisive.
Reference index
| Reference |
Topics |
| references/build-and-frontend.md |
Bundling, HTML/CSS, loaders, plugins, sourcemaps, bytecode, and executables |
| references/databases-and-storage.md |
Bun.SQL, PostgreSQL, MySQL, SQLite, Redis, S3, archives, and secrets |
| references/http-and-networking.md |
Bun.serve(), routes, fetch, WebSockets, sockets, TLS, DNS, proxies, and cookies |
| references/node-compatibility.md |
Node core APIs, workers, process behavior, VM, inspector, native addons, and compatibility gaps |
| references/packages-and-workspaces.md |
Installs, lockfiles, dependencies, workspaces, registries, audits, and publishing |
| references/runtime-and-platform.md |
Bun-native APIs, JavaScript/Web APIs, shell, subprocesses, formats, profiling, and platforms |
| references/testing.md |
bun:test, discovery, concurrency, isolation, sharding, coverage, mocks, and snapshots |
Breaking changes and upgrade traps
TLS verification is stricter
fetch() runs tls.checkServerIdentity before sending request bytes and for
every redirect hop.
tls.connect({ host }) uses host for SNI and certificate identity.
Bun.connect(), socket.upgradeTLS(), RedisClient, and listener APIs with
requestCert: true verify by default. Supply the correct ca and
servername, or use literal rejectUnauthorized: false only when intended.
The reported Node boundary changed
- Bun reports Node.js 26, native-addon ABI
147, and Node-API version 10.
- The obsolete
res.writeHeader() alias is removed; use writeHead().
- A paused
readable.read() without a size returns one buffered chunk, not the
whole buffer.
FFI C strings are JavaScript strings
- A
cstring return or callback argument is now a string; a null pointer is
null.
new CString(ptr) returns a string without .ptr, .byteLength, or
.arrayBuffer. Preserve the original pointer when native code must free it.
Lockfiles migrate forward
- New
bun.lock files use lockfileVersion: 2; existing v0/v1 files migrate
during bun install.
- Nested or version-scoped overrides require version 3, which older Bun
releases cannot read.
Environment loading depends on invocation mode
- When Bun is invoked as
node through bun --bun, bunx --bun, or a node
symlink, it does not auto-load .env* files.
- Pass
node --env-file=.env script.js when Node mode needs that file.
- Outside Node mode,
bun run --no-env-file or root-level env = false skips
automatic discovery; an explicit --env-file is still loaded.
Structured-data parsing is stricter
- YAML follows YAML 1.2:
yes, no, on, and off are strings; only
true and false spellings are booleans.
Bun.JSONC.parse() throws SyntaxError for invalid or empty input.
- TOML rejects unquoted strings, adjacent key/value pairs without a newline,
and integers beyond
Number.MAX_SAFE_INTEGER.
Loader and transform behavior changed
- Runtime
.css imports default-export {} rather than an absolute path.
- Bare
import "." and import ".." resolve a directory's package entry or
index file rather than a same-named sibling.
- New projects select TypeScript 7-compatible settings and
typescript@^7.
"jsx": "react-jsx" selects production jsx/jsxs; use
"react-jsxdev" explicitly for jsxDEV.
Socket, mapping, cron, and shell parameters changed
Bun.Socket#setKeepAlive(true, initialDelay) treats the delay as
milliseconds; values below 1000 leave TCP_KEEPIDLE unchanged.
Bun.mmap(path, { offset }) exposes the requested byte at index zero; remove
old page-alignment compensation.
Bun.cron.parse() and in-process Bun.cron() use local time. Pass
{ tz: "UTC" } as the final argument to retain UTC.
Bun.$ expands only literal *, **, and braces in the template. Patterns
from interpolation, variables, command substitution, or quotes stay literal.
Fetch and server conformance tightened
- Duplicate response/request headers are comma-joined except
Set-Cookie,
which remains available through getSetCookie().
- Cloning a consumed or locked body throws immediately. Network failures reject
with
TypeError and mark a failed body as used.
- A method route uses
GET for HEAD only when no HEAD handler exists.
- Invalid
Bun.serve() ports throw; an invalid response status goes through
error() to a default 500 response.
Mock, containment, and SQL semantics tightened
jest.resetAllMocks() and vi.resetAllMocks() now discard implementations
as well as call history; use clearAllMocks() to retain implementations.
toContain() uses ===: -0 matches 0, while NaN does not match itself.
- MySQL
DATETIME and TIMESTAMP values decode as UTC. MariaDB JSON columns
decode to JavaScript values.
- PostgreSQL honors
PGSSLMODE unless a URL option overrides it, and infinite
dates/timestamps decode as numeric infinities.
Package-manager edge cases changed
- Project
bunfig.toml wins over .npmrc for duplicate settings.
bun update <missing-name> fails rather than adding the package.
--production limits updates to production and optional dependencies;
interactive mode updates only the selection.
- With non-TTY input,
bun init behaves as -y, while bun update -i errors.
- New workspace projects use isolated installs; existing projects can retain a
hoisted default recorded by the lockfile's
configVersion.
Older migration hazards still matter
Bun.serve() uses routes rather than the earlier static option.
Bun.build() rejects on build errors; set throw: false to inspect an error
result instead.
bun -p means --print, not --port.
- Bare
bun build --sourcemap creates linked maps; request inline maps with
--sourcemap=inline.
- Package scripts start in the directory containing the discovered
package.json, not the invoking shell's subdirectory.
Bun.Build.Target was renamed to Bun.Build.CompileTarget.
High-value package workflows
- Inspect why a package exists with
bun why <package>.
- Preview dependency source changes with
bun pm diff; it flags changed files,
new lifecycle scripts, and new sensitive built-in imports.
- Remediate advisories with
bun audit fix --dry-run, then bun audit fix;
major-version fixes require --latest.
- Consolidate compatible duplicate versions with
bun dedupe; use --check
in CI.
- Remove packages absent from the lockfile with
bun prune; add
--production to remove development dependencies.
bun update updates transitive dependencies. Selectors can be names or globs
and can use --latest.
bun add, bun remove, and bun update accept --filter; web... includes
dependencies and ...web includes dependents.
bun add <pkg> --catalog writes the root catalog and uses catalog: in the
workspace.
High-value server and fetch APIs
Serve directories directly through routes:
Bun.serve({
routes: { "/static/*": { dir: "./public" } },
});
Directory routes handle content types, validators, conditional and range
requests, and index.html. Paths are normalized; on Linux, symlinks cannot
escape the route root.
Compress buffered fetch bodies with compress; streaming bodies are unchanged:
await fetch(url, {
method: "POST",
body: largeJsonString,
compress: "gzip",
});
Use Request.textStream() or Response.textStream() for decoded UTF-8 string
streams that preserve split multibyte characters, strip a leading BOM, and
replace invalid sequences.
High-value build and executable APIs
- Enable the built-in React auto-memoization compiler with
bun build --react-compiler or reactCompiler: true.
- Embed assets with repeatable
bun build --compile --asset <path>; locate them
relative to import.meta.dir.
Bun.isStandaloneExecutable reports whether code is in a compiled binary.
- Embedded native libraries can be opened with
dlopen().
- Standalone builds can use
splitting: true, and embedded CommonJS entrypoints
can require one another.
- For a self-contained browser file, compile HTML with
bun build --compile --target=browser ./index.html; every entrypoint must be
HTML and splitting is unavailable in this mode.
High-value testing workflows
- Use
bun test --isolate for a fresh global per file and cleanup between files.
- Use
bun test --parallel[=N] for worker-process distribution; it implies
isolation.
- Use
bun test --shard=M/N for deterministic CI shards.
- Use
bun test --changed[=ref] to select tests through the import graph.
- Record durations with
--update-timings, then use --timings=<path> to
balance shards and prioritize slow files.
- Use
--path-ignore-patterns or test.pathIgnorePatterns to prune discovery.
- Concurrent tests cannot use assertion-count checks or file snapshots; inline
snapshots remain supported.
expectTypeOf assertions are runtime no-ops; also run
bunx tsc --noEmit for type tests.
High-value data and storage APIs
Bun.SQL selects PostgreSQL, MySQL/MariaDB, or SQLite from its URL or adapter
and uses tagged queries across adapters.
- SQL object helpers omit
undefined insert properties so defaults apply, and
bulk inserts collect columns across every row.
- SQLite
sql.unsafe() and sql.file() accept named parameter objects.
Bun.s3 provides lazy Blob-like files, reads, writes, multipart writers,
listings, presigned URLs, Requester Pays, and response metadata controls.
- Redis supports binary reads, database URL paths, Pub/Sub, TLS, retry cleanup,
and reconnectable duplicates.
Bun.Archive reads and creates tar archives and can write locally or to S3.
Compatibility boundaries
The detailed compatibility reference distinguishes implemented Node APIs from
remaining gaps. In particular, verify code that depends on exact
node:perf_hooks behavior, V8 serialization interchange, low-level promise
hooks, child-process socket-handle IPC, or Node module-loader internals. Later
entries in that reference supersede earlier compatibility snapshots when the
project runs the later release.
1---2name: bun-knowledge-patch3description: Bun4license: MIT5---678# Bun Knowledge Patch910Use this skill for Bun runtime, package-manager, bundler, test-runner, server,11database, and Node.js-compatibility work. Establish the project's actual Bun12release before applying version-attributed guidance from the references.1314Read only the references relevant to the task. When project code, tests, or15observed behavior disagree with this guidance, treat the project as decisive.1617## Reference index1819| Reference | Topics |20| --- | --- |21| [references/build-and-frontend.md](references/build-and-frontend.md) | Bundling, HTML/CSS, loaders, plugins, sourcemaps, bytecode, and executables |22| [references/databases-and-storage.md](references/databases-and-storage.md) | `Bun.SQL`, PostgreSQL, MySQL, SQLite, Redis, S3, archives, and secrets |23| [references/http-and-networking.md](references/http-and-networking.md) | `Bun.serve()`, routes, fetch, WebSockets, sockets, TLS, DNS, proxies, and cookies |24| [references/node-compatibility.md](references/node-compatibility.md) | Node core APIs, workers, process behavior, VM, inspector, native addons, and compatibility gaps |25| [references/packages-and-workspaces.md](references/packages-and-workspaces.md) | Installs, lockfiles, dependencies, workspaces, registries, audits, and publishing |26| [references/runtime-and-platform.md](references/runtime-and-platform.md) | Bun-native APIs, JavaScript/Web APIs, shell, subprocesses, formats, profiling, and platforms |27| [references/testing.md](references/testing.md) | `bun:test`, discovery, concurrency, isolation, sharding, coverage, mocks, and snapshots |2829## Breaking changes and upgrade traps3031### TLS verification is stricter3233- `fetch()` runs `tls.checkServerIdentity` before sending request bytes and for34 every redirect hop.35- `tls.connect({ host })` uses `host` for SNI and certificate identity.36- `Bun.connect()`, `socket.upgradeTLS()`, `RedisClient`, and listener APIs with37 `requestCert: true` verify by default. Supply the correct `ca` and38 `servername`, or use literal `rejectUnauthorized: false` only when intended.3940### The reported Node boundary changed4142- Bun reports Node.js 26, native-addon ABI `147`, and Node-API version 10.43- The obsolete `res.writeHeader()` alias is removed; use `writeHead()`.44- A paused `readable.read()` without a size returns one buffered chunk, not the45 whole buffer.4647### FFI C strings are JavaScript strings4849- A `cstring` return or callback argument is now a string; a null pointer is50 `null`.51- `new CString(ptr)` returns a string without `.ptr`, `.byteLength`, or52 `.arrayBuffer`. Preserve the original pointer when native code must free it.5354### Lockfiles migrate forward5556- New `bun.lock` files use `lockfileVersion: 2`; existing v0/v1 files migrate57 during `bun install`.58- Nested or version-scoped overrides require version 3, which older Bun59 releases cannot read.6061### Environment loading depends on invocation mode6263- When Bun is invoked as `node` through `bun --bun`, `bunx --bun`, or a `node`64 symlink, it does not auto-load `.env*` files.65- Pass `node --env-file=.env script.js` when Node mode needs that file.66- Outside Node mode, `bun run --no-env-file` or root-level `env = false` skips67 automatic discovery; an explicit `--env-file` is still loaded.6869### Structured-data parsing is stricter7071- YAML follows YAML 1.2: `yes`, `no`, `on`, and `off` are strings; only72 `true` and `false` spellings are booleans.73- `Bun.JSONC.parse()` throws `SyntaxError` for invalid or empty input.74- TOML rejects unquoted strings, adjacent key/value pairs without a newline,75 and integers beyond `Number.MAX_SAFE_INTEGER`.7677### Loader and transform behavior changed7879- Runtime `.css` imports default-export `{}` rather than an absolute path.80- Bare `import "."` and `import ".."` resolve a directory's package entry or81 index file rather than a same-named sibling.82- New projects select TypeScript 7-compatible settings and `typescript@^7`.83- `"jsx": "react-jsx"` selects production `jsx`/`jsxs`; use84 `"react-jsxdev"` explicitly for `jsxDEV`.8586### Socket, mapping, cron, and shell parameters changed8788- `Bun.Socket#setKeepAlive(true, initialDelay)` treats the delay as89 milliseconds; values below 1000 leave `TCP_KEEPIDLE` unchanged.90- `Bun.mmap(path, { offset })` exposes the requested byte at index zero; remove91 old page-alignment compensation.92- `Bun.cron.parse()` and in-process `Bun.cron()` use local time. Pass93 `{ tz: "UTC" }` as the final argument to retain UTC.94- `Bun.$` expands only literal `*`, `**`, and braces in the template. Patterns95 from interpolation, variables, command substitution, or quotes stay literal.9697### Fetch and server conformance tightened9899- Duplicate response/request headers are comma-joined except `Set-Cookie`,100 which remains available through `getSetCookie()`.101- Cloning a consumed or locked body throws immediately. Network failures reject102 with `TypeError` and mark a failed body as used.103- A method route uses `GET` for `HEAD` only when no `HEAD` handler exists.104- Invalid `Bun.serve()` ports throw; an invalid response status goes through105 `error()` to a default `500` response.106107### Mock, containment, and SQL semantics tightened108109- `jest.resetAllMocks()` and `vi.resetAllMocks()` now discard implementations110 as well as call history; use `clearAllMocks()` to retain implementations.111- `toContain()` uses `===`: `-0` matches `0`, while `NaN` does not match itself.112- MySQL `DATETIME` and `TIMESTAMP` values decode as UTC. MariaDB JSON columns113 decode to JavaScript values.114- PostgreSQL honors `PGSSLMODE` unless a URL option overrides it, and infinite115 dates/timestamps decode as numeric infinities.116117### Package-manager edge cases changed118119- Project `bunfig.toml` wins over `.npmrc` for duplicate settings.120- `bun update <missing-name>` fails rather than adding the package.121- `--production` limits updates to production and optional dependencies;122 interactive mode updates only the selection.123- With non-TTY input, `bun init` behaves as `-y`, while `bun update -i` errors.124- New workspace projects use isolated installs; existing projects can retain a125 hoisted default recorded by the lockfile's `configVersion`.126127### Older migration hazards still matter128129- `Bun.serve()` uses `routes` rather than the earlier `static` option.130- `Bun.build()` rejects on build errors; set `throw: false` to inspect an error131 result instead.132- `bun -p` means `--print`, not `--port`.133- Bare `bun build --sourcemap` creates linked maps; request inline maps with134 `--sourcemap=inline`.135- Package scripts start in the directory containing the discovered136 `package.json`, not the invoking shell's subdirectory.137- `Bun.Build.Target` was renamed to `Bun.Build.CompileTarget`.138139## High-value package workflows140141- Inspect why a package exists with `bun why <package>`.142- Preview dependency source changes with `bun pm diff`; it flags changed files,143 new lifecycle scripts, and new sensitive built-in imports.144- Remediate advisories with `bun audit fix --dry-run`, then `bun audit fix`;145 major-version fixes require `--latest`.146- Consolidate compatible duplicate versions with `bun dedupe`; use `--check`147 in CI.148- Remove packages absent from the lockfile with `bun prune`; add149 `--production` to remove development dependencies.150- `bun update` updates transitive dependencies. Selectors can be names or globs151 and can use `--latest`.152- `bun add`, `bun remove`, and `bun update` accept `--filter`; `web...` includes153 dependencies and `...web` includes dependents.154- `bun add <pkg> --catalog` writes the root catalog and uses `catalog:` in the155 workspace.156157## High-value server and fetch APIs158159Serve directories directly through routes:160161```ts162Bun.serve({163 routes: { "/static/*": { dir: "./public" } },164});165```166167Directory routes handle content types, validators, conditional and range168requests, and `index.html`. Paths are normalized; on Linux, symlinks cannot169escape the route root.170171Compress buffered fetch bodies with `compress`; streaming bodies are unchanged:172173```ts174await fetch(url, {175 method: "POST",176 body: largeJsonString,177 compress: "gzip",178});179```180181Use `Request.textStream()` or `Response.textStream()` for decoded UTF-8 string182streams that preserve split multibyte characters, strip a leading BOM, and183replace invalid sequences.184185## High-value build and executable APIs186187- Enable the built-in React auto-memoization compiler with188 `bun build --react-compiler` or `reactCompiler: true`.189- Embed assets with repeatable `bun build --compile --asset <path>`; locate them190 relative to `import.meta.dir`.191- `Bun.isStandaloneExecutable` reports whether code is in a compiled binary.192- Embedded native libraries can be opened with `dlopen()`.193- Standalone builds can use `splitting: true`, and embedded CommonJS entrypoints194 can require one another.195- For a self-contained browser file, compile HTML with196 `bun build --compile --target=browser ./index.html`; every entrypoint must be197 HTML and splitting is unavailable in this mode.198199## High-value testing workflows200201- Use `bun test --isolate` for a fresh global per file and cleanup between files.202- Use `bun test --parallel[=N]` for worker-process distribution; it implies203 isolation.204- Use `bun test --shard=M/N` for deterministic CI shards.205- Use `bun test --changed[=ref]` to select tests through the import graph.206- Record durations with `--update-timings`, then use `--timings=<path>` to207 balance shards and prioritize slow files.208- Use `--path-ignore-patterns` or `test.pathIgnorePatterns` to prune discovery.209- Concurrent tests cannot use assertion-count checks or file snapshots; inline210 snapshots remain supported.211- `expectTypeOf` assertions are runtime no-ops; also run212 `bunx tsc --noEmit` for type tests.213214## High-value data and storage APIs215216- `Bun.SQL` selects PostgreSQL, MySQL/MariaDB, or SQLite from its URL or adapter217 and uses tagged queries across adapters.218- SQL object helpers omit `undefined` insert properties so defaults apply, and219 bulk inserts collect columns across every row.220- SQLite `sql.unsafe()` and `sql.file()` accept named parameter objects.221- `Bun.s3` provides lazy Blob-like files, reads, writes, multipart writers,222 listings, presigned URLs, Requester Pays, and response metadata controls.223- Redis supports binary reads, database URL paths, Pub/Sub, TLS, retry cleanup,224 and reconnectable duplicates.225- `Bun.Archive` reads and creates tar archives and can write locally or to S3.226227## Compatibility boundaries228229The detailed compatibility reference distinguishes implemented Node APIs from230remaining gaps. In particular, verify code that depends on exact231`node:perf_hooks` behavior, V8 serialization interchange, low-level promise232hooks, child-process socket-handle IPC, or Node module-loader internals. Later233entries in that reference supersede earlier compatibility snapshots when the234project runs the later release.