---
title: Bun v1.0.30
description: Fixes 27 bugs (addressing 103 👍 reactions), fixes an 8x perf regression in 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
date: "2024-03-04T09:25:31.452Z"
author: jarred
draft: false
---

Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager &mdash; 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`](/blog/bun-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 Shell
- [`v1.0.28`](/blog/bun-v1.0.28) fixes 6 bugs (addressing 26 👍 reactions). Fixes bugs impacting Prisma and Astro, `node:events`, `node:readline`, and `node:http2`. Fixes a bug in Bun Shell involving stdin redirection and fixes bugs in `bun:test` with `test.each` and `describe.only`.
- [`v1.0.27`](/blog/bun-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:

{% codetabs %}

```sh#curl
$ curl -fsSL https://bun.sh/install | bash
```

```sh#npm
$ npm install -g bun
```

```sh#brew
$ brew tap oven-sh/bun
$ brew install bun
```

```sh#docker
$ docker pull oven/bun
$ docker run --rm --init --ulimit memlock=-1:-1 oven/bun
```

{% /codetabs %}

To upgrade Bun:

```sh
$ 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:

```js
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.

```sh
# 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`:

```ts
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](https://github.com/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.

```js
test("expect.assertions()", () => {
  expect.assertions(1);
  expect(true).toBe(true);
});

test("expect.hasAssertions()", () => {
  expect.hasAssertions();
  expect(true).toBe(true);
});
```

Thanks to [@Yash-Singh1](https://github.com/Yash-Singh1) for implementing this feature!

## `Bun.fileURLToPath(url)` now supports strings

`Bun.fileURLToPath(url)` now supports strings as well as URL objects.

```js
// 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](https://github.com/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:

```ts
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:

```js
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](https://github.com/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](https://github.com/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.

```js
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.

```js
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.

```sh
$ ln -s /path/to/real.js /path/to/symlink.js
```

```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](https://github.com/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](https://github.com/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:

```js
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](https://github.com/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:

```js
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](https://github.com/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.

## Thanks to 14 contributors!

- [@kyr0](https://github.com/kyr0)
- [@nektro](https://github.com/nektro)
- [@almmiko](https://github.com/almmiko)
- [@lgarron](https://github.com/lgarron)
- [@paperclover](https://github.com/paperclover)
- [@Electroid](https://github.com/Electroid)
- [@argosphil](https://github.com/argosphil)
- [@camero2734](https://github.com/camero2734)
- [@igorwessel](https://github.com/igorwessel)
- [@lucasmichot](https://github.com/lucasmichot)
- [@marvinruder](https://github.com/marvinruder)
- [@Yash-Singh1](https://github.com/Yash-Singh1)
- [@zackradisic](https://github.com/zackradisic)
- [@dylan-conway](https://github.com/dylan-conway)
- [@Jarred-Sumner](https://github.com/Jarred-Sumner)
