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.10
fixes 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.9
fixes 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.0
Bundows. Windows support is here!
To install Bun
curl -fsSL https://bun.sh/install | bash
npm install -g bun
powershell -c "irm bun.sh/install.ps1|iex"
scoop install bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun
To upgrade Bun
bun upgrade
Fixed: 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 install
bun install v1.1.11
Checked 9 installs across 10 packages (no changes) [5.00ms]
bun install
bun install v1.1.11
Checked 9 installs across 10 packages (no changes) [5.00ms]
Previously:
bun-1.1.10 install
bun install v1.1.10
- work2@workspace:packages/work2
- work3@workspace:packages/work3
2 packages installed [4.00ms]
bun-1.1.0 install
bun 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.ts
bun 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.ts
bun 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 @paperdave.
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 @paperdave.
Fixed: External imports with backslashes
On Windows, building the following code with --external
would fail:
bun build --external="*" ./index.js
import { loadFonts } from "../base";
console.log(loadFonts);
Thanks to @paperdave 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.