{"slug": "bun-v1-3-11", "title": "Bun v1.3.11", "summary": "Bun v1.3.11 reduces its Linux x64 binary size by 4 MB by removing CMake, and introduces a new `Bun.cron` API for cross-platform OS-level cron job management. The update also adds `Bun.sliceAnsi`, a high-performance built-in for ANSI-aware string slicing that replaces the `slice-ansi` and `cli-truncate` npm packages. Additionally, `Bun.markdown.render()` now provides richer metadata to list-related callbacks, enabling custom list numbering without workarounds.", "body_md": "#### To install Bun\n\n```\ncurl -fsSL https://bun.sh/install | bash\nnpm install -g bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\nscoop install bun\nbrew tap oven-sh/bun\nbrew install bun\ndocker pull oven/bun\ndocker run --rm --init --ulimit memlock=-1:-1 oven/bun\n```\n\n#### To upgrade Bun\n\n```\nbun upgrade\n```\n\n[4 MB smaller on Linux x64](#4-mb-smaller-on-linux-x64)\n\nIn the next version of Bun\n\n— Bun (@bunjavascript)\n\nBun gets 4 MB smaller on Linux x64 because we deleted CMake[pic.twitter.com/HQPacwNO3O][March 14, 2026]\n\n`Bun.cron`\n\n— OS-level Cron Jobs and Expression Parsing\n\n`Bun.cron`\n\n— OS-level Cron Jobs and Expression ParsingBun now includes a built-in `Bun.cron`\n\nAPI for registering OS-level cron jobs, parsing cron expressions, and removing scheduled jobs — all cross-platform.\n\n[Register a cron job](#register-a-cron-job)\n\n```\n// Register a cron job (crontab on Linux, launchd on macOS, Task Scheduler on Windows)\nawait Bun.cron(\"./worker.ts\", \"30 2 * * MON\", \"weekly-report\");\n```\n\nWhen the OS scheduler fires, Bun imports the script and calls `default.scheduled()`\n\n, following the [Cloudflare Workers Cron Triggers API](https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/):\n\n```\n// worker.ts\nexport default {\n  async scheduled(controller) {\n    // controller.cron === \"30 2 * * 1\"\n    // controller.scheduledTime === 1737340200000\n    await doWork();\n  },\n};\n```\n\n[Parse cron expressions](#parse-cron-expressions)\n\n``` js\nconst next = Bun.cron.parse(\"*/15 * * * *\"); // next quarter-hour\nconst weekday = Bun.cron.parse(\"0 9 * * MON-FRI\"); // next weekday at 9 AM UTC\nconst yearly = Bun.cron.parse(\"@yearly\"); // next January 1st\n\n// Chain calls to get a sequence\nconst first = Bun.cron.parse(\"0 * * * *\", from);\nconst second = Bun.cron.parse(\"0 * * * *\", first);\n```\n\nReturns a `Date`\n\nor `null`\n\nif no match exists within ~4 years (e.g. February 30th).\n\n[Remove a job](#remove-a-job)\n\n```\nawait Bun.cron.remove(\"weekly-report\");\n```\n\n[Cron expression features](#cron-expression-features)\n\n**Standard 5-field format** with`*`\n\n,`,`\n\n,`-`\n\n,`/`\n\noperators**Named days and months**:`MON`\n\n–`SUN`\n\n,`JAN`\n\n–`DEC`\n\n(case-insensitive, full names supported)**Nicknames**:`@yearly`\n\n,`@monthly`\n\n,`@weekly`\n\n,`@daily`\n\n,`@hourly`\n\n**POSIX OR logic**: when both day-of-month and day-of-week are restricted, either matching fires the job** Sunday as 7**: weekday field accepts both`0`\n\nand`7`\n\n[Platform backends](#platform-backends)\n\n| Platform | Backend | Logs |\n|---|---|---|\n| Linux | `crontab` | `journalctl -u cron` |\n| macOS | `launchd` plist | `/tmp/bun.cron.<title>.{stdout,stderr}.log` |\n| Windows | `schtasks` | Event Viewer → TaskScheduler |\n\nRe-registering with the same title overwrites the existing job in-place.\n\n`Bun.sliceAnsi`\n\n— ANSI & grapheme-aware string slicing\n\n`Bun.sliceAnsi`\n\n— ANSI & grapheme-aware string slicingA new built-in that replaces both the [ slice-ansi](https://www.npmjs.com/package/slice-ansi) and\n\n[npm packages.](https://www.npmjs.com/package/cli-truncate)\n\n`cli-truncate`\n\n`Bun.sliceAnsi`\n\nslices strings by terminal column width while preserving ANSI escape codes (SGR colors, OSC 8 hyperlinks) and respecting grapheme cluster boundaries (emoji, combining marks, flags).\n\n```\n// Plain slice (replaces slice-ansi)\nBun.sliceAnsi(\"\\x1b[31mhello\\x1b[39m\", 1, 4); // \"\\x1b[31mell\\x1b[39m\"\n\n// Truncation with ellipsis (replaces cli-truncate)\nBun.sliceAnsi(\"unicorn\", 0, 4, \"…\"); // \"uni…\"\nBun.sliceAnsi(\"unicorn\", -4, undefined, \"…\"); // \"…orn\"\n```\n\nThe ellipsis is emitted **inside** active SGR styles (inherits color/bold) so truncated text stays visually consistent, but **outside** hyperlinks to avoid broken links. Negative indices are supported for slicing from the end.\n\nAn optional `{ ambiguousIsNarrow }`\n\noption is available for controlling East Asian ambiguous width behavior, matching `Bun.stringWidth`\n\nand `Bun.wrapAnsi`\n\n.\n\n[Performance](#performance)\n\nUses a three-tier dispatch strategy:\n\n**SIMD ASCII fast path**— pure ASCII input is handled with a single SIMD scan and zero-copy when nothing is cut** Single-pass streaming**— non-negative indices (the common case) walk the input once with stack-only allocation** Two-pass for negative indices**— computes total width first, then emits\n\n`Bun.markdown.render()`\n\nnow passes richer metadata to `listItem`\n\nand `list`\n\ncallbacks\n\n`Bun.markdown.render()`\n\nnow passes richer metadata to `listItem`\n\nand `list`\n\ncallbacksThe `listItem`\n\ncallback in `Bun.markdown.render()`\n\nnow receives `index`\n\n, `depth`\n\n, `ordered`\n\n, and `start`\n\nin its metadata object, and the `list`\n\ncallback now includes `depth`\n\n. Previously, `listItem`\n\nonly received `checked`\n\n(and only for task list items), making it impossible to know an item's position, nesting level, or parent list type without workarounds.\n\nThis makes it straightforward to implement custom list markers like nested numbering schemes (`1.`\n\n/ `a.`\n\n/ `i.`\n\n) without regex post-processing:\n\n``` js\nconst result = Bun.markdown.render(\n  \"1. first\\n   1. sub-a\\n   2. sub-b\\n2. second\",\n  {\n    listItem: (children, { index, depth, ordered, start }) => {\n      const n = (start ?? 1) + index;\n      const marker = !ordered\n        ? \"-\"\n        : depth === 0\n        ? `${n}.`\n        : `${String.fromCharCode(96 + n)}.`;\n      return \"  \".repeat(depth) + marker + \" \" + children.trimEnd() + \"\\n\";\n    },\n    list: (children) => \"\\n\" + children,\n  },\n);\n// 1. first\n//   a. sub-a\n//   b. sub-b\n// 2. second\n```\n\nThe full `listItem`\n\nmeta shape is now:\n\n| Property | Type | Description |\n|---|---|---|\n`index` | `number` | 0-based position within the parent list |\n`depth` | `number` | Nesting level of the parent list (0 = top-level) |\n`ordered` | `boolean` | Whether the parent list is ordered |\n`start` | `number | undefined` | Start number of the parent list (only set when ordered) |\n`checked` | `boolean | undefined` | Task list state (only set for `- [x]` / `- [ ]` items) |\n\n**Breaking change:** The `listItem`\n\ncallback now **always** receives the meta object (previously it was only passed for task list items). `start`\n\nand `checked`\n\nare `undefined`\n\nwhen not applicable, keeping the object shape fixed for monomorphic inline caches.\n\nMeta objects use cached JSC structures internally, adding ~0.7ns per object overhead — effectively free.\n\n`--path-ignore-patterns`\n\nfor `bun test`\n\n`--path-ignore-patterns`\n\nfor `bun test`\n\nYou can now exclude files and directories from test discovery using glob patterns with the new `--path-ignore-patterns`\n\nflag or `test.pathIgnorePatterns`\n\nin `bunfig.toml`\n\n.\n\nThis is useful when your project contains submodules, vendored code, or other directories with `*.test.ts`\n\nfiles that you don't want `bun test`\n\nto pick up. Matched directories are pruned during scanning, so their contents are never traversed — ignoring a large directory tree is efficient.\n\n```\n# bunfig.toml\n[test]\npathIgnorePatterns = [\n  \"vendor/**\",\n  \"submodules/**\",\n  \"fixtures/**\",\n  \"**/test-data/**\"\n]\n```\n\nOr via the command line:\n\n```\nbun test --path-ignore-patterns 'vendor/**' --path-ignore-patterns 'fixtures/**'\n```\n\nCommand-line `--path-ignore-patterns`\n\nflags override the `bunfig.toml`\n\nvalue entirely — the two are not merged.\n\nThanks to @ctjlewis and @alii for the contribution!\n\n[Fixed ](#fixed-dgram-udp-socket-bugs-on-macos)`dgram`\n\nUDP socket bugs on macOS\n\n`dgram`\n\nUDP socket bugs on macOSFixed three bugs in UDP socket creation that caused `dgram`\n\nsockets to silently fail on macOS:\n\n: The`reusePort`\n\nnow works on macOS`reusePort: true`\n\noption was previously gated to Linux only. It now works on any platform that supports`SO_REUSEPORT`\n\n.**Implicit bind-on-send works on macOS**: Calling`send()`\n\non an unbound UDP socket should implicitly bind to`0.0.0.0`\n\non a random port (matching Node.js behavior). Hardcoded Linux errno values (`92`\n\ninstead of the`ENOPROTOOPT`\n\nmacro) prevented IPv4 fallback paths from being taken on macOS, where`ENOPROTOOPT`\n\nis`42`\n\n.**Socket fd leak on failure**: When`setsockopt`\n\nfor reuse failed, the socket file descriptor was leaked and no diagnostic errno was propagated, producing generic \"Failed to bind socket\" errors.\n\nThis affected real-world libraries like [ k-rpc](https://github.com/mafintosh/k-rpc) (used by\n\n[) that rely on implicit binding behavior.](https://github.com/webtorrent/bittorrent-dht)\n\n`bittorrent-dht`\n\n``` python\nimport dgram from \"dgram\";\n\nconst socket = dgram.createSocket(\"udp4\");\n\n// This now correctly auto-binds on macOS, matching Node.js behavior\nsocket.send(Buffer.from(\"hello\"), 0, 5, 41234, \"127.0.0.1\", (err) => {\n  if (err) console.error(\"send error:\", err);\n  else console.log(\"sent successfully\");\n\n  const addr = socket.address();\n  console.log(\"bound to:\", addr); // Shows auto-assigned port\n  socket.close();\n});\n```\n\n[Native ARM64 shim for Windows ](#native-arm64-shim-for-windows-node-modules-bin-binaries)`node_modules/.bin`\n\nbinaries\n\n`node_modules/.bin`\n\nbinariesThe `bun_shim_impl.exe`\n\nused for `node_modules/.bin/*`\n\non Windows was previously hardcoded to x86_64, meaning every package binary invocation on Windows ARM64 ran under x64 emulation. The shim is now compiled natively for aarch64 when building Bun for Windows ARM64, removing the emulation overhead.\n\nThanks to @dylan-conway for the contribution!\n\n[Bugfixes](#bugfixes)\n\n[Node.js compatibility improvements](#node-js-compatibility-improvements)\n\n- Fixed: An operator precedence bug in native readable streams caused\n`0 < MIN_BUFFER_SIZE`\n\nto be evaluated before the`??`\n\noperator, resulting in excessive memory allocation when processing stream chunks - Fixed: Custom\n`lookup`\n\nfunction in Node.js`http`\n\n/`https`\n\nclient (e.g. via axios) breaking TLS certificate verification with`ERR_TLS_CERT_ALTNAME_INVALID`\n\nor`unknown certificate verification error`\n\n. When a custom DNS lookup resolved a hostname to an IP address, the original hostname was lost, causing TLS SNI and certificate verification to fail. - Fixed:\n`fs.openSync`\n\nand`fs.promises.open`\n\nthrowing`EINVAL`\n\non Windows when passed numeric flags from`fs.constants`\n\n(e.g.`O_CREAT | O_TRUNC | O_WRONLY`\n\n). The`fs.constants`\n\nvalues on Windows use native MSVC values which differ from Bun's internal representation, causing flags like`O_CREAT`\n\nto be silently dropped. This also fixes`UV_FS_O_FILEMAP`\n\nsupport, which unbreaks packages like`tar@7`\n\n(used by`npm`\n\n,`giget`\n\n, and others) that silently failed to extract files on Windows. (@Hona) - Fixed:\n`fs.stat`\n\ntruncating sub-millisecond precision from`mtimeMs`\n\n,`atimeMs`\n\n,`ctimeMs`\n\n, and`birthtimeMs`\n\nproperties, now returning fractional milliseconds matching Node.js behavior - Fixed:\n`fs.watch()`\n\ncrash on Windows when a failed watch is retried on the same path - Fixed: a crash in\n`fs.watchFile`\n\n- Fixed:\n`node:fs`\n\nfunctions crashing with certain inputs - Fixed: crash (\n`cast causes pointer to be null`\n\n) on Windows when`fs.realpathSync`\n\nor`fs.readlink`\n\nencountered certain edge-case filesystem configurations like ramdisk volumes, substituted drives, or standalone executables in unusual locations - Fixed:\n`console.Console`\n\nreturning`undefined`\n\npermanently after being accessed during a near-stack-overflow condition (@sosukesuzuki) - Fixed:\n`Buffer.compare`\n\nnot properly validating`targetEnd`\n\nand`sourceEnd`\n\noffset bounds, where certain combinations of start/end values could bypass range checks instead of throwing`ERR_OUT_OF_RANGE`\n\nas Node.js does - Fixed: rare crash in\n`Buffer.indexOf`\n\n,`Buffer.lastIndexOf`\n\n, and`Buffer.includes`\n\n- Fixed: buffer overflow in path-handling code\n- Fixed:\n`process.off(\"SIGxxx\", handler)`\n\nremoving one of multiple signal listeners would incorrectly uninstall the OS signal handler, causing remaining listeners to stop receiving signals - Fixed:\n`execFileSync`\n\nand`execSync`\n\nerrors containing a self-referencing cycle (`err.error === err`\n\n) that caused`JSON.stringify(err)`\n\nto throw - Fixed:\n`spawnSync`\n\ncould accidentally drain the global microtask queue, executing user JavaScript during what should be a synchronous, blocking call. - Fixed: missing BoringSSL error clearing in\n`crypto.createPrivateKey()`\n\n- Fixed: Crash in\n`crypto.Hash`\n\n`update()`\n\n/`digest()`\n\ncaused by missing`this`\n\nvalidation, a GC hazard on input strings during encoding conversion, and reading from detached buffers. Now properly throws`ERR_INVALID_THIS`\n\nand`ERR_INVALID_STATE`\n\ninstead of crashing. - Fixed: crashs when calling native crypto/stream prototype methods (like\n`Hmac.digest()`\n\n,`DiffieHellmanGroup.verifyError`\n\n) with an invalid`this`\n\nvalue — now correctly throws`ERR_INVALID_THIS`\n\ninstead of crashing - Fixed:\n`X509Certificate.prototype`\n\nwas`undefined`\n\n, which prevented subclassing with`class Foo extends X509Certificate {}`\n\n(@sosukesuzuki) - Fixed:\n`getPeerCertificate()`\n\nreturning`undefined`\n\ninstead of`{}`\n\nwhen no peer certificate is available, which caused`checkServerIdentity()`\n\nto crash with`TypeError: Cannot destructure property 'subject' from null or undefined value`\n\nduring TLS handshakes — most notably when connecting to MongoDB Atlas clusters - Fixed: hypothetical out of bounds read/write in native zlib\n`write()`\n\n/`writeSync()`\n\nwhere user-controlled offset and length parameters were not properly validated in production builds. These now correctly throw`ERR_OUT_OF_RANGE`\n\n,`ERR_INVALID_ARG_TYPE`\n\n, and other appropriate errors. - Fixed:\n`dgram.createSocket()`\n\nincorrectly set`SO_REUSEADDR`\n\non all UDP sockets, allowing multiple processes to silently bind to the same port without throwing`EADDRINUSE`\n\n— diverging from Node.js behavior.`SO_REUSEADDR`\n\nis now only applied when`reuseAddr: true`\n\nis explicitly passed. - Fixed: a latent GC safety issue in\n`node:vm`\n\nmodules where a garbage collection cycle during object construction could lead to a crash (@sosukesuzuki) - Fixed:\n`structuredClone()`\n\nthrowing`DataCloneError`\n\non objects created via`napi_create_object`\n\n, matching Node.js behavior (@dylan-conway) - Fixed:\n`node:http2`\n\nclient streams stalling after receiving 65,535 bytes when using`setLocalWindowSize()`\n\n— the method updated the internal connection window size but never sent a`WINDOW_UPDATE`\n\nframe to the peer, causing the server to stop sending data once the default window was exhausted - Fixed:\n`node:http2`\n\n`getPackedSettings`\n\n,`getUnpackedSettings`\n\n, and`getDefaultSettings`\n\nnow match Node.js behavior, including support for`enableConnectProtocol`\n\n,`customSettings`\n\n, correct`enablePush`\n\ndefault, and proper`ERR_HTTP2_INVALID_SETTING_VALUE`\n\nerror codes (@cirospaciari) - Fixed: crash that could occur on exit when using NAPI native addon modules (such as\n`skia-canvas`\n\n) on Windows - Fixed: bug in libuv on Windows that could cause pipe data loss when reading from subprocess pipes\n\n[Bun APIs](#bun-apis)\n\n- Fixed PgBouncer incompatibility with\n`sql.prepare(false)`\n\nqueries - Fixed:\n`Bun.file().text()`\n\nand similar async read methods not keeping event loop alive when an error errors - Fixed: Incorrect\n`Bun.file()`\n\nasync read error paths on Windows - Fixed:\n`Bun.file().stat()`\n\nand`Bun.file().delete()`\n\ncorrupting file paths containing non-ASCII UTF-8 characters (e.g., German umlauts, Japanese characters, emoji), causing`ENOENT`\n\nerrors due to double-encoding - Fixed:\n`Bun.stdin.stream()`\n\nand`Bun.stdin.text()`\n\nreturning empty on Linux after calling`Bun.stdin.exists()`\n\nor accessing`Bun.stdin.size`\n\n- Fixed:\n`Bun.JSONL.parseChunk(input, start, end)`\n\nnow honors`start`\n\n/`end`\n\noffsets when`input`\n\nis a string. - Fixed:\n`S3File.slice(0, N).stream()`\n\nignoring the slice range and downloading the entire file instead of only the requested byte range - Fixed:\n`bun:sql`\n\npanicking with \"integer does not fit in destination type\" when a PostgreSQL query exceeded the 65,535 parameter limit (e.g. batch inserting 7,000 rows × 10 columns). Now throws a descriptive`PostgresError`\n\nwith code`ERR_POSTGRES_TOO_MANY_PARAMETERS`\n\nand a hint to reduce batch size - Fixed: Valkey RESP protocol parser no longer crashes with a stack overflow on deeply nested server responses by enforcing a maximum nesting depth of 128 for aggregate types (@dylan-conway)\n- Fixed:\n`Bun.Transpiler`\n\nignoring`experimentalDecorators: true`\n\nand`emitDecoratorMetadata: true`\n\nfrom tsconfig, always emitting TC39-style decorators instead of legacy TypeScript decorators. This broke frameworks like Angular that rely on legacy decorator calling conventions in JIT mode. - Fixed:\n`Bun.Transpiler.scanImports()`\n\nand`Bun.Transpiler.scan()`\n\nignoring the`trimUnusedImports`\n\noption — unused imports were only being trimmed by`transformSync()`\n\n- Fixed: memory leak in\n`Bun.Transpiler`\n\nwhen using a custom`tsconfig`\n\nwith async`transform()`\n\ncalls. After the first`await transpiler.transform()`\n\n, subsequent calls could read freed memory or double-free the tsconfig pointer, potentially causing crashes. - Fixed:\n`emitDecoratorMetadata: true`\n\nin tsconfig.json without`experimentalDecorators: true`\n\nincorrectly used TC39 standard decorators instead of legacy decorator semantics, causing NestJS, TypeORM, Angular, and other legacy-decorator frameworks to crash with`descriptor.value`\n\nundefined - Fixed: Breakpoints landing at wrong line numbers when debugging files over 50KB in VSCode's debug terminal (\n`BUN_INSPECT`\n\nenv var). The runtime transpiler cache was not being disabled when the debugger was activated via the`BUN_INSPECT`\n\nenvironment variable (as opposed to`--inspect`\n\nCLI flags), causing cached output without inline source maps to be used. (@alii) - Fixed: HTML-referenced assets (favicons, images, etc.) returning 404 when served with\n`Bun.serve()`\n\nbecause they were missing from the bundle manifest's`files`\n\narray despite being correctly emitted to disk - Fixed\n`ReadableStream`\n\nwith`type: \"direct\"`\n\nincorrectly calling the user's`cancel`\n\ncallback on normal stream completion - Fixed: Empty string arguments in Bun shell\n- Fixed: DoS in\n`Bun.stringWidth`\n\n- Fixed:\n`Bun.stringWidth`\n\ngrapheme bug: ANSI escape bytes were incorrectly included in grapheme break tracking\n\n[Web APIs](#web-apis)\n\n- Fixed: incorrect value in\n`WebSocket.prototype.protocol`\n\nin certain cases - Fixed:\n`ws.ping()`\n\nand`ws.pong()`\n\ncalled without arguments incorrectly sent non-empty payloads instead of empty control frames, causing disconnections with strict WebSocket servers (e.g. Binance) that validate pong payloads match ping payloads (@gaowhen) - Fixed: WebSocket client now validates the\n`Sec-WebSocket-Accept`\n\nheader value during the upgrade handshake per RFC 6455 §4.2.2, rejecting connections where the server returns a stale or mismatched response - Fixed:\n`Request.formData()`\n\ntruncating small binary files with null bytes - Fixed: a crash when calling\n`fetch()`\n\nusing a very large number of headers - Fixed: crash in fetch with TLS proxies in certain cases\n- Fixed: Edgecase with pipelined HTTP requests with no headers\n- Fixed: HTTP header value incorrect stripping for certain cases\n- Hardened Bun's HTTP server against malformed chunked transfer requests. Thanks to @sim1222 for reporting issues.\n- Fixed: CRLF injection vulnerability in\n`ServerResponse.prototype.writeEarlyHints`\n\nwhere header names and values were written to the socket without validation, allowing HTTP response splitting attacks - Fixed: WebSocket connections dropping over proxy tunnels with bidirectional traffic\n\n[bun install](#bun-install)\n\n- Fixed:\n`bun install`\n\nhanging indefinitely or silently skipping processing when a security scanner is enabled and the project has more than ~790 packages. The package list is now sent to the scanner subprocess via an IPC pipe instead of command-line arguments, avoiding OS argument length limits - Fixed:\n`bun install`\n\nhanging indefinitely (~300 seconds per dependency) when using an HTTP proxy (`http_proxy`\n\n/`https_proxy`\n\n) with cached packages that return`304 Not Modified`\n\nthrough a CONNECT tunnel (@WhiteMinds) - Fixed: Non-deterministic\n`bun install`\n\nbug where transitive peer dependencies were left unresolved when all manifest loads were synchronous (e.g., warm cache with valid`Cache-Control: max-age`\n\n), causing missing peer dependency symlinks with`--linker=isolated`\n\n(@dylan-conway) - Fixed:\n`.npmrc`\n\nauth token matching only comparing hostnames - Fixed:\n`bun install`\n\nsilently exiting with code 1 when the security scanner encounters an error, making failures impossible to debug (especially in CI). All error paths now print descriptive messages to stderr. - Fixed:\n`bun install`\n\nnow shows an accurate error message when a`file:`\n\ndependency path is missing (e.g., due to a stale lockfile), instead of the misleading \"Bun could not find a package.json file to install from\" message. The new error clearly identifies the dependency and the exact path that was not found. - Fixed:\n`bun update -i`\n\nselect all ('A' key) now correctly updates packages instead of showing \"No packages selected for update\" - Fixed:\n`bun pack`\n\nand`bun publish`\n\nusing stale`version`\n\nand`name`\n\nfrom`package.json`\n\nwhen lifecycle scripts (`prepublishOnly`\n\n,`prepack`\n\n,`prepare`\n\n) modify them during execution. Previously, the tarball filename and publish registry metadata would use the original values captured before scripts ran. (@dylan-conway) - Fixed:\n`bun bun.lockb | head`\n\nno longer prints an internal`BrokenPipe`\n\nerror message instead of exiting silently\n\n[JavaScript bundler](#javascript-bundler)\n\n- Fixed:\n`bun build --compile --bytecode --format=esm`\n\ncrashing at runtime with \"Cannot find module\" errors when barrel-optimized packages (those with`\"sideEffects\": false`\n\n) had unused re-exports recorded as external dependencies in bytecode ModuleInfo (@Jarred-Sumner) - Fixed:\n`import Bun from 'bun'`\n\nreturning`undefined`\n\nwhen bundled with`--bytecode`\n\nflag. The CJS lowering pass was incorrectly generating`globalThis.Bun.default`\n\ninstead of`globalThis.Bun`\n\nfor default imports. - Fixed: Bundler dropping exports when barrel files with\n`sideEffects: false`\n\nre-export namespace imports (`import * as X from './mod'; export { X }`\n\n), causing`ReferenceError`\n\nfor the re-exported bindings at runtime - Fixed: Bundler barrel optimization incorrectly dropped exports needed by dynamic\n`import()`\n\nwhen the same barrel was also referenced by a static named import, producing invalid JS with undeclared export bindings (`SyntaxError`\n\nat runtime). This commonly affected AWS SDK builds using`@smithy/credential-provider-imds`\n\n. (@dylan-conway) - Fixed: dynamic\n`import()`\n\nwith import attributes (e.g.`{ with: { type: 'text' } }`\n\n) not applying the correct loader during bundling, which caused`--compile`\n\nbuilds to fail with`require_* is not defined`\n\nfor`.html`\n\nfiles imported as text - Fixed:\n`bun build --compile`\n\nwith HTML routes producing relative asset URLs (`./chunk-abc.js`\n\n) that broke when served from nested routes like`/foo/`\n\n— assets now use absolute root-relative URLs (`/chunk-abc.js`\n\n) - Fixed: Crash when resolving very long import paths (e.g. through tsconfig\n`baseUrl`\n\n,`paths`\n\nwildcards, or`node_modules`\n\nlookups) - Fixed: Dev server barrel optimizer incorrectly deferring\n`export *`\n\ntarget submodules, causing classes like`QueryClient`\n\nto become`undefined`\n\nand throwing`TypeError: Right-hand side of 'instanceof' is not an object`\n\n— affected packages like`@refinedev/core`\n\nwith`@tanstack/react-query`\n\n[CSS Parser](#css-parser)\n\n- Fixed: CSS bundler incorrectly mapping logical border-radius properties (\n`border-start-start-radius`\n\n,`border-start-end-radius`\n\n,`border-end-start-radius`\n\n,`border-end-end-radius`\n\n) to only`border-top-left-radius`\n\n/`border-top-right-radius`\n\nwhen values contain`var()`\n\nreferences. All four logical properties now correctly resolve to their distinct physical counterparts. - Fixed: CSS\n`mask`\n\nshorthand parsing incorrectly dropping`geometry-box`\n\nvalues like`padding-box`\n\nand`content-box`\n\n, which could also cause rules with different geometry boxes to be incorrectly merged (@anthonybaldwin) - Fixed:\n`unicode-range`\n\nvalues in`@font-face`\n\nrules being mangled by the CSS processor (e.g.,`U+0000-00FF`\n\nbecame`U0-0FF`\n\n), which caused browsers to silently ignore the entire`@font-face`\n\nrule and fonts to not load\n\n[bun test](#bun-test)\n\n- Fixed:\n`bun test`\n\nobject diffs and`console.log`\n\nsilently dropping properties with empty string keys (`\"\"`\n\n)\n\n[Bun Shell](#bun-shell)\n\n- Fixed: shell interpolation could crash given invalid input\n- Fixed: Bun's builtin\n`rm`\n\nin the shell returning exit code 0 instead of the correct non-zero exit code when a file doesn't exist and`.quiet()`\n\nor`.text()`\n\nis used. This also caused errors to never be thrown in those code paths.\n\n[TypeScript types](#typescript-types)\n\n- Fixed: Missing\n`contentEncoding`\n\nproperty in the`S3Options`\n\nTypeScript type definition, which caused TypeScript errors and missing IDE autocompletion when using the`contentEncoding`\n\noption added in Bun v1.3.7\n\n[Runtime and CLI](#runtime-and-cli)\n\n- Fixed:\n`bun run --filter`\n\nand`bun run --workspaces`\n\nfailing when the`NODE`\n\nenvironment variable points to a non-existent file. Bun now validates that the path is an executable before using it, and falls back to searching`PATH`\n\nor creating its own node symlink. - Fixed: 100% CPU spin on Linux caused by the inotify file watcher re-parsing stale events in an infinite loop when a single\n`read()`\n\nreturned more than 128 events - Fixed crashes when passing Proxy-wrapped arrays to built-in APIs (@sosukesuzuki)", "url": "https://wpnews.pro/news/bun-v1-3-11", "canonical_source": "https://bun.com/blog/bun-v1.3.11", "published_at": "2026-03-18 04:16:10+00:00", "updated_at": "2026-05-22 20:40:10.275339+00:00", "lang": "en", "topics": ["developer-tools", "open-source"], "entities": ["Bun", "Cloudflare", "CMake"], "alternates": {"html": "https://wpnews.pro/news/bun-v1-3-11", "markdown": "https://wpnews.pro/news/bun-v1-3-11.md", "text": "https://wpnews.pro/news/bun-v1-3-11.txt", "jsonld": "https://wpnews.pro/news/bun-v1-3-11.jsonld"}}