Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager — all in one.
This release fixes 27 bugs (addressing 103 👍 reactions), fixes an 8x perf regression to Bun.serve(), adds a new --conditions
flag to bun build
and Bun's runtime, adds support for expect.assertions()
and expect.hasAssertions()
in Bun's test runner, fixes crashes and improves Node.js compatibility.
Previous releases
v1.0.29
fixes 8 bugs. Bun.stringWidth(a) is a ~6,756x faster drop-in replacement for the popular 'string-width' package. bunx checks for updates more frequently. Adds expect().toBeOneOf() in bun:test. Memory leak impacting Prisma is fixed. Shell now supports advanced redirects like '2>&1', '&>'. Reliability improvements to bunx, bun install, WebSocket client, and Bun Shellv1.0.28
fixes 6 bugs (addressing 26 👍 reactions). Fixes bugs impacting Prisma and Astro,node:events
,node:readline
, andnode:http2
. Fixes a bug in Bun Shell involving stdin redirection and fixes bugs inbun:test
withtest.each
anddescribe.only
.v1.0.27
fixes 72 bugs (addressing 192 👍 reactions), Bun Shell supports throwing on non-zero exit codes, stream Response bodies using async generators, improves reliability of fetch(), http2 client, Bun.Glob fixes. Fixes a regression with bun --watch on Linux. Improves Node.js compatibility
To install Bun:
curl -fsSL https://bun.sh/install | bash
npm install -g 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: 8x performance regression in Bun.serve()
in certain cases
A performance regression when using streams to write exactly one chunk of data to the response body in a single tick of the event loop has been fixed in Bun.serve()
. This regression was introduced in v1.0.4.
The following code sometimes reproduces the issue:
Bun.serve({
async fetch(req) {
return new Response(
new ReadableStream({
type: "direct",
async pull(controller) {
controller.write("hello");
await controller.end();
},
}),
);
},
});
Tip: when using nginx with Bun, make sure to set proxy_http_version 1.1
in your nginx configuration. HTTP Keep-Alive is important for performance, and nginx by default disables it.
New flag: --conditions
The --conditions
flag allows you to specify a list of conditions to use when resolving packages from package.json "exports"
.
This flag is supported in both bun build
and Bun's runtime.
# Use it with bun build:
bun build --conditions="react-server" --target=bun ./app/foo/route.js
# Use it with bun's runtime:
bun --conditions="react-server" ./app/foo/route.js
Bun already supported package.json "exports"
, this release adds support for adding additional conditions to target.
You can also use conditions
programmatically with Bun.build
:
await Bun.build({
conditions: ["react-server"],
target: "bun",
entryPoints: ["./app/foo/route.js"],
});
This CLI flag is also supported by Node.js with the same syntax.
Thanks to @igorwessel for implementing this feature!
expect.assertions()
and expect.hasAssertions()
are now supported
expect.assertions()
and expect.hasAssertions()
are now supported in Bun's test runner.
test("expect.assertions()", () => {
expect.assertions(1);
expect(true).toBe(true);
});
test("expect.hasAssertions()", () => {
expect.hasAssertions();
expect(true).toBe(true);
});
Thanks to @Yash-Singh1 for implementing this feature!
Bun.fileURLToPath(url)
now supports strings
Bun.fileURLToPath(url)
now supports strings as well as URL objects.
// new:
Bun.fileURLToPath("file:///path/to/file.txt");
// old (still works):
Bun.fileURLToPath(new URL("file:///path/to/file.txt"));
Bun Shell better stacktraces on error
Bun Shell now provides better stacktraces on error.
Previously, Bun Shell would not include the full stacktrace when an error occurred. This has been fixed, thanks to @zackradisic.
Fixed: potential crash in Bun.serve()
with delayed request bodies
A crash that could potentially occur when sending a buffered response after receiving a request body has been fixed.
The following code sometimes reproduces the issue:
Bun.serve({
development: true,
async fetch(request: Request): Promise<Response> {
await Bun.sleep(200 + Math.random() * 100);
const body = await (async function () {
return await request.json();
})();
return new Response(JSON.stringify(body));
},
});
This crash occurred because Bun will automatically reject pending Promises that consume requests when the request aborts, and Bun's code was not checking that the Promise to read the request body was still pending before attempting to reject the Promise. Rejecting the Promise triggered an assertion failure internally, which led to the crash.
Fixed: Headers with underscores and uppercase names in Bun.serve()
Bun v1.0.28 added support for receiving headers with underscores in Bun.serve(). For several reasons, Bun.serve() automatically lowercases all incoming header names (HTTP headers are case insensitive by the spec). A bug in the HTTP server's code for lowercasing header names caused the underscore to be invalid in the header name, leading to unexpected behavior. This has been fixed.
Fixed: textEncoder.encode()
JIT bug under certain conditions
A bug in the side effects configuration in TextEncoder.prototype.encode
caused it to potentially return unexpected results when called thousands of times in a short loop when no allocations occur between calls. This has been fixed.
Fixed: Crash when printing error stacks with mocked functions
A bug in Bun's implementation of mock functions caused a crash when printing error stack traces that contain an anonymous mock function. This has been fixed.
The following test reproduces the crash:
test("#8794", () => {
const target = {
a() {
throw new Error("a");
return 1;
},
method() {
return target.a();
},
};
spyOn(target, "method");
for (let i = 0; i < 20; i++) {
try {
target.method();
expect.unreachable();
} catch (e) {
e.stack;
expect(e.stack).toContain("at method ");
expect(e.stack).toContain("at a ");
}
Bun.gc(false);
}
});
Fixed: crash in expect(undefined).toContainKeys(a)
expect(undefined).toContainKeys(array)
no longer crashes the test runner. This crash occurred due to missing a check for an object-like expect() value in the toContainKeys
matcher.
Thanks to @dylan-conway for fixing this bug.
Fixed: Potential crash with timers in event loop
An uninitialized memory access in the event loop library used by Bun could lead to a crash after about 16 minutes in certain cases. This crash could be reproduced most frequently on Linux ARM64 builds of Bun. Thanks to @argosphil for fixing this bug.
Node.js compatiblity improvements
This release includes several Node.js compatibility improvements.
isKeyObject
in util/types
is implemented
The isKeyObject
function in node:util/types
is implemented. This function returns true if the input is a KeyObject.
import { isKeyObject } from "node:util/types";
import { generateKeyPairSync } from "node:crypto";
isKeyObject({}); // false
isKeyObject(generateKeyPairSync("ed25519").publicKey); // true
fdatasync
in node:fs is implemented
Bun now implements fdatasync
in node:fs
. This function synchronously writes all changes made to the file to disk.
import { fdatasync } from "node:fs";
fdatasync(fd);
require.main
with symlinks behaves like Node.js
Bun now behaves like Node.js when using require.main
with symlinks.
ln -s /path/to/real.js /path/to/symlink.js
// symlink.js
console.log(require.main === module); // true
This helps address a compatibility issue when running prisma generate
using Bun.
Fixed: crash in napi_get_buffer_info
When using the napi_get_buffer_info
function in a native addon and passing a null pointer for the size argument, Bun no longer crashes.
Fixed: Emit end-of-file correctly in Node.js Readable
A bug in our node:stream
implementation caused the readable
event to be emitted in a microtask instead of process.nextTick
. This has been fixed, thanks to @camero2734.
This bug impacted prisma generate
and other tools that use Node.js streams.
Fixed: missing event in node:streams impacting node-fetch
A bug in our node:streams
implementation where we called destroy
on the stream on the next tick after calling this.push(null)
led to node:streams
not destroying the stream correctly. This bug caused node-fetch
to never finish reading the response body. This bug impacted prisma generate
and other tools that bundle node-fetch
into their package.
Bun internally overrides node-fetch
to use the fetch
global provided by Bun, so packages using node-fetch
directly were not impacted by this bug.
Thanks to @camero2734 for fixing this bug.
Fixed: 'request.endsWith is not a function' error in Next.js
When using Bun to run a Next.js app, after a large number of requests you might run into an error like this:
57 | }).bind(null, resolveFilename, hookPropertyMap);
58 | // This is a hack to make sure that if a user requires a Next.js module that wasn't bundled
59 | // that needs to point to the rendering runtime version, it will point to the correct one.
60 | // This can happen on `pages` when a user requires a dependency that uses next/image for example.
61 | mod.prototype.require = function(request) {
62 | if (request.endsWith(".shared-runtime")) {
^
TypeError: request.endsWith is not a function. (In 'request.endsWith(".shared-runtime")', 'request.endsWith' is undefined)
at node_modules/next/dist/server/require-hook.js:62:9
at getMiddleware (node_modules/next/dist/server/next-server.js:904:26)
at node_modules/next/dist/server/base-server.js:173:32
at node_modules/next/dist/server/base-server.js:172:50
at node_modules/next/dist/server/base-server.js:275:34
This bug has been fixed. Our implementation of require
was incorrectly using the tailcall intrinsic in JavaScriptCore which sometimes led to arguments in the function being forwarded to bound functions incorrectly.
Fixed: cp
function in node:fs
with relative paths
A regression in v1.0.27 intended for Windows support caused the cp
function in node:fs
to not handle relative paths correctly. This bug has been fixed, thanks to @argosphil.
Fixed: process.stdin
ends too early
Given a large enough input, the following code would incorrectly lose one of the last chunks of data:
const { Transform } = require("node:stream");
let totalChunkSize = 0;
const uppercase = new Transform({
transform(chunk, _encoding, callback) {
totalChunkSize += chunk.length;
callback(null, "");
},
});
process.stdin.pipe(uppercase).pipe(process.stdout);
process.stdin.on("end", () => console.log(totalChunkSize));
This impacted prisma generate
, amongst others. Thanks to @camero2734 for fixing it.
Windows support is coming in Bun v1.1.0
We are still working on Windows support. We are making progress, but it's not ready yet. You will see a release with Windows support soon.