Bun v1.1.11 is here! This release Fixes 36 bugs (addressing 362 👍). bun update saves dependency updates to package.json. A peer dependencies resolution bug in bun install is fixed. setTimeout gets 5x faster throughput on Linux. Node.js compatibility improvements to fs, zlib, timers, http, dgram and module. Event loop improvements on macOS. Windows reliability improvements.
We're hiring systems engineers in San Francisco to build the future of JavaScript!
Previous releases
v1.1.10fixes 20 bugs. 2x faster uncached bun install on Windows.fetch()uses up to 2.8x less memory. Several bugfixes to bun install, sourcemaps, Windows reliability improvements and Node.js compatibility improvementsv1.1.9fixes 67 bugs (addressing 150 👍). Fixes to: workspaces inbun install, sourcemaps in bun build, IPv6 & VPN connectivity, Loading UNC paths, junctions, symlinks, and pnpm on Windows,fetch()gets faster, addeddns.prefetch()API,atob()gets 8x faster,toString('base64url')gets 5x faster, expect().toBeReturned() matcher, Node.js compatibility improvements, Bun Shell fixes, and lots more bugfixes.v1.1.0Bundows. Windows support is here!
To install Bun
curl -fsSL https://bun.sh/install | bashnpm install -g bunpowershell -c "irm bun.sh/install.ps1|iex"scoop install bunbrew tap oven-sh/bunbrew install bundocker pull oven/bundocker run --rm --init --ulimit memlock=-1:-1 oven/bunTo upgrade Bun
bun upgradeFixed: bun update writes to package.json
We fixed a long-standing bug where bun update would update dependencies, but only write the changes to the bun.lockb and not the package.json.
To help prevent breaking changes, bun update preserves the semver ranges when choosing which dependencies to update. If you want to update to the latest version, use bun update --latest.
Thanks to @dylan-conway for implementing this!
Fixed: bun install peer dependencies resolution
A bug that could cause peer dependencies to be hoisted incorrectly has been fixed, thanks to @dylan-conway. This bug would frequently reproduce with the ajv and expo npm packages.
Here's an example of an error this bug could cause:
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module 'ajv/dist/compile/codegen'
Require stack:
- repro/node_modules/ajv-keywords/dist/definitions/typeof.js
- repro/node_modules/ajv-keywords/dist/keywords/typeof.js
- repro/node_modules/ajv-keywords/dist/keywords/index.js
- repro/node_modules/ajv-keywords/dist/index.js
- repro/node_modules/schema-utils/dist/validate.js
- repro/node_modules/schema-utils/dist/index.js
- repro/node_modules/babel-loader/lib/index.js
- repro/node_modules/loader-runner/lib/loadLoader.js
- repro/node_modules/loader-runner/lib/LoaderRunner.js
- repro/node_modules/webpack/lib/NormalModuleFactory.js
- repro/node_modules/webpack/lib/Compiler.js
- repro/node_modules/webpack/lib/webpack.js
- repro/node_modules/webpack/lib/index.js
- repro/node_modules/webpack-cli/lib/webpack-cli.js
- repro/node_modules/webpack-cli/lib/bootstrap.js
- repro/node_modules/webpack-cli/bin/cli.js
- repro/node_modules/webpack/bin/webpack.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1144:15)
at Module._load (node:internal/modules/cjs/loader:985:27)
at Module.require (node:internal/modules/cjs/loader:1235:19)
at require (node:internal/modules/helpers:176:18)
at Object.<anonymous> (repro/node_modules/ajv-keywords/dist/definitions/typeof.js:3:19)
at Module._compile (node:internal/modules/cjs/loader:1376:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12)
at Module.require (node:internal/modules/cjs/loader:1235:19)
We've added integrations tests in Bun's repository to prevent this type of bug from occurring again.
Fixed: bun install no longer relinks workspaces every time
A bug in bun install led to workspaces being relinked every time, even when they didn't need to be.
Now:
bun installbun install v1.1.11
Checked 9 installs across 10 packages (no changes) [5.00ms]
bun installbun install v1.1.11
Checked 9 installs across 10 packages (no changes) [5.00ms]Previously:
bun-1.1.10 installbun install v1.1.10
- work2@workspace:packages/work2
- work3@workspace:packages/work3
2 packages installed [4.00ms]
bun-1.1.0 installbun install v1.1.10
- work2@workspace:packages/work2
- work3@workspace:packages/work3
2 packages installed [4.00ms]Thanks to @dylan-conway for implementing this!
New: 5x faster setTimeout throughput
We've re-implemented setTimeout, setImmediate, and setInterval to improve performance, fix bugs and address Node.js compatibility issues.
Running setTimeout 2,000,000 times on Linux x64
Every call to setTimeout, setInterval, or setImmediate has a cost. In this release, we've reduced the cost of setTimeout by 5x on Linux.
| Delta | Runtime | Execution time | Peak RSS |
|---|---|---|---|
| - | Bun v1.1.11 | 648 ms | 484 MB |
| 5x | Bun v1.1.10 | 3454 ms | 710 MB |
| 1.8x | Node.js 22 | 1182 ms | 487 MB |
Fixed: setTimeout this value is now a Timeout object
In Bun, this was previously undefined. In Node.js, this in a setTimeout callback is a Timeout object. This was a bug, and we've fixed it.
setTimeout(function () {
console.log(this); // Timeout
}, 1000);
As before, you can continue to pass clearTimeout either the Timeout object or the timeout ID.
const timer = setTimeout(() => {}, 1000);
// Timeout implements Symbol.toPrimitive, which lets you use it as a number:
const myTimerID = timer[Symbol.toPrimitive]();
const myTimerID2 = timer + 0;
clearTimeout(timer);
clearTimeout(myTimerID);
clearTimeout(myTimerID2);
This fix also applies to setInterval and setImmediate.
Fixed: setInterval rescheduling behavior matches Node.js
In Node.js, setInterval timers are rescheduled based on when the timer callback was called.
That means if you have a slow synchronous callback, the next interval will be scheduled based on when the callback started, not when it finished.
let last = performance.now();
setInterval(function () {
const now = performance.now();
console.log("It's been", (now - last) | 0, "ms since the last interval");
for (let i = 0; i < 1e9; i++) {}
this.refresh();
last = performance.now();
}, 500);
In Bun v1.1.11 and Node.js v22, this code prints something like:
❯ bun set.js # Bun v1.1.11 & Node.js v22
It's been 502 ms since the last interval
It's been 0 ms since the last interval
It's been 231 ms since the last interval
It's been 239 ms since the last interval
It's been 247 ms since the last interval
It's been 244 ms since the last interval
It's been 220 ms since the last interval
It's been 220 ms since the last interval
Previously, Bun would print:
❯ bun set.js # Bun v1.1.10 and earlier
It's been 502 ms since the last interval
It's been 501 ms since the last interval
It's been 499 ms since the last interval
It's been 501 ms since the last interval
It's been 501 ms since the last interval
It's been 501 ms since the last interval
It's been 501 ms since the last interval
It's been 501 ms since the last interval
Fixed: setTimeout shouldn't await promises
Previously, Bun would await promises returned from setTimeout and setInterval.
This meant the following code would hang:
setTimeout(async () => {
return new Promise();
}, 1000);
Bun no longer awaits promises returned from setTimeout and setInterval.
Thanks to @zawodskoj for fixing this!
Node.js compatibility improvements
This release includes several Node.js compatibility improvements.
Fixed: fs.promises.cp should create directories on Linux
On Linux, fs.promises.cp now creates directories if they don't exist. This matches Node.js behavior, and already worked as expected on Windows and macOS.
Thanks to @nektro for fixing this!
Fixed: node:zlib brotli parameters
A bug in node:zlib prevented setting the params argument in zlib.brotliCompress and zlib.brotliDecompress. This has been fixed, thanks to @nektro.
New: addAbortListener and getMaxListeners in node:evenets
The addAbortListener and getMaxListeners methods have been implemented in node:events (for EventEmitter, but not for EventTarget yet).
Fixed: path.toNamespacedPath with backslash edgecase
An edgecase in path.toNamespacedPath has been fixed, thanks to @dylan-conway and @huseyinacacak-janea. This bug also ocurred in Node.js.
The following assertions now pass:
assert.strictEqual(path.win32.toNamespacedPath("\\\\?\\foo\\"), "\\\\?\\foo\\");
assert.strictEqual(path.win32.toNamespacedPath("\\\\?\\foo"), "\\\\?\\foo\\");
assert.strictEqual(
path.win32.toNamespacedPath("\\\\?\\c:\\Windows/System"),
"\\\\?\\c:\\Windows\\System",
);
Fixed: node:http server max body size
Node.js doesn't set a max request body size by default. Bun sets a default max request body size, and a bug caused it to also be applied to the node:http server's max request body size. This has been fixed, thanks to @JonnyBurger.
Fixed: Uncaught exceptions now fail in bun test
When an uncaught exception occurs between test cases, Bun makes it more clear that it happened between test cases.
Breaking change: The exit code of bun test is now 1 when an uncaught exception or unhandled rejection occurs between test cases. This is what it should always have been, and what you'd expect from a test runner.
import { test, expect } from "bun:test";
test("uncaught rejection", async () => {
setTimeout(() => {
throw new Error("Uh-oh!");
}, 100);
await Bun.sleep(99);
});
Now this outputs:
bun test a.test.tsbun test v1.1.11
a.test.ts:
✓ uncaught rejection [100.05ms]
# Unhandled error between tests
-------------------------------
1 | import { test, expect } from "bun:test";
2 |
3 | test("uncaught rejection", async () => {
4 | setTimeout(() => {
5 | throw new Error("Uh-oh!");
^
error: Uh-oh!
at a.test.ts:5:11
-------------------------------
1 pass
0 fail
1 error
Ran 1 tests across 1 files. [106.00ms]
Previously, this output was less clear. It didn't clearly show the error occurred between test cases and it did not show a count of how many rejection errors occurred.
bun-1.1.10 test a.test.tsbun test v1.1.10 (5102a944)
a.test.ts:
✓ uncaught rejection [100.32ms]
1 | import { test, expect } from "bun:test";
2 |
3 | test("uncaught rejection", async () => {
4 | setTimeout(() => {
5 | throw new Error("Uh-oh!");
^
error: Uh-oh!
at a.test.ts:5:11
1 pass
0 fail
Ran 1 tests across 1 files. [111.00ms]
Fixed: Custom function name in stack traces
When you set the name property of a function dynamically, Bun now uses that name in stack traces.
const fn = function OriginalName() {
console.trace();
};
Object.defineProperty(fn, "name", { value: "NewName" });
fn();
In Bun v1.1.11, this code prints:
at NewName (abc.js:2:3)
at abc.js:5:1
Previously, Bun would print:
at OriginalName (abc.js:2:3)
at abc.js:5:1
This regressed in Bun v0.6.12 and has been fixed, thanks to @refi64. We've added a test to prevent this from happening again.
Fixed: Sourcemaps with code splitting
When code splitting is enabled in bun build, a bug could cause minified sourcemaps to be invalid in some cases. This has been fixed, thanks to @paperclover.
macOS reliability improvements
macOS, Linux, and Windows each use different system calls to wait for I/O-related events. On macOS, a bug in our event loop code could cause Bun to wait extra time for I/O events to occur. Previously, we assumed that a kqueue event would only be either readable or writable:
int events = LIBUS_SOCKET_READABLE;
if (kev.flags & EVFILT_WRITE) {
events = LIBUS_SOCKET_WRITABLE;
}
This was incorrect. A kqueue event can be both readable and writable. We've fixed this bug.
Fixed: Hang in UDP sockets
Reading from UDP sockets in Bun could hang on macOS x64 and Windows x64. This was caused by an issue in our event loop code. We've fixed this bug.
Windows reliability improvements
Fixed: Bun.build CPU usage
A bug causing transpiler threads in Bun.build on Windows to spin loop infinitely using CPU has been fixed, thanks to @paperclover.
Fixed: External imports with backslashes
On Windows, building the following code with --external would fail:
bun build --external="*" ./index.jsimport { loadFonts } from "../base";
console.log(loadFonts);
Thanks to @paperclover for fixing this!
Fixed: Various DNS issues on Windows
We've updated the c-ares asynchronous DNS resolution library which fixes several bugs on Windows that make it more consistent with Linux and macOS.
Fuzz testing
Fuzz testing parts of Bun's runtime APIs led to several bugfixes in this release.
Fixed: Crash when calling Bun.CryptoHasher without new
A mistake in Bun's JavasScriptCore bindings generator led to a crash when calling Bun.CryptoHasher without new. This has been fixed. We've added a test to ensure this doesn't happen again.
Fixed: Crash on Linux when reading a Bun.file() errors
A crash that could occur when reading a Bun.file() asynchronously errors on Linux has been fixed. This was reported several times and reproduced by a new test.
Fixed: Crash in Bun.$.escape() without arguments
A crash has been fixed when calling Bun.$.escape() without arguments. This was reproduced by a new test.
Fixed: Crash in bun:ffi read fn without arguments
When calling read.u32() in bun:ffi without arguments, a crash could occur. This has been fixed.
Fixed: Crash in Node.js Module.prototype._compile
When no arguments or invalid arguments were passed to Module.prototype._compile, a crash could occur when an exception was thrown. This has been fixed.
Fixed: Crash in CryptoHasher.byteLength
A crash could occur when calling Bun.CryptoHasher.byteLength with certain hash algorithms. This has been fixed, thanks to @nektro.