---
title: Bun v1.0.22
description: "Fixes `bun install` issues on Vercel, adds `performance.mark()` APIs, adds `child_process` support for extra pipes, makes `Buffer.concat` 10% - 400% faster, adds `toBeEmptyObject` and `toContainKeys` matchers, fixes `console.table` width using emojis, and adds support for `argv` and `execArgv` options in `worker_threads`."
date: "2024-01-09T22:27:17+00:00"
author: ashcon
draft: false
---

Bun v1.0.22 fixes 29 bugs (addressing 118 👍 reactions), fixes `bun install` issues on Vercel, adds `performance.mark()` APIs, adds `child_process` support for extra pipes, makes `Buffer.concat` faster, adds `toBeEmptyObject` and `toContainKeys` matchers, fixes `console.table` width using emojis, and support for `argv` and `execArgv` options in `worker_threads`, and supports Brotli in `fetch`.

Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager &mdash; all in one. In case you missed it, here are some of the recent changes to Bun:

- [`v1.0.21`](/blog/bun-v1.0.21) - Fixes 33 bugs (addressing 80 👍 reactions). `console.table()` support. `Bun.write`, Bun.file, and bun:sqlite use less memory. Large file uploads with FormData use less memory. bun:sqlite error messages get more detailed. Memory leak in errors from node:fs fixed. Node.js compatibility improvements, and many crashes fixed.
- [`v1.0.20`](/blog/bun-v1.0.20) - Reduces memory usage in `fs.readlink`, `fs.readFile`, `fs.writeFile`, `fs.stat` and `HTMLRewriter`. Fixes a regression where setTimeout caused high CPU usage on Linux. `HTMLRewriter.transform` now supports strings and `ArrayBuffer`. `fs.writeFile()` and `fs.readFile()` now support `hex` & `base64` encodings. `Bun.spawn` shows how much CPU & memory the process used.
- [`v1.0.19`](/blog/bun-v1.0.19) - Fixes 26 bugs (addressing 92 👍 reactions). Use @types/bun instead of bun-types. Fixes --frozen-lockfile bug. bcrypt & argon2 packages now work. setTimeout & setInterval get 4x higher throughput. module mocks in bun:test resolve specifiers. Optimized spawnSync() for large stdio on Linux. Bun.peek() gets 90x faster, expect(map1).toEqual(map2) gets 100x faster. Bugfixes to NAPI, bun install, and Node.js compatibility improvements.

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: Issues with `bun install` on Vercel

In a recent release of Bun, we introduced changes to `bun install` to make lifecycle scripts run faster by running them in parallel. When doing this, we also changed the how Bun sets the current working directory for lifecycle scripts, and started to use the [`posix_spawn_file_actions_addchdir_np`](https://docs.oracle.com/cd/E88353_01/html/E37843/posix-spawn-file-actions-addchdir-np-3c.html) C-standard library function.

Bun was not properly checking if that function failed. The function was introduced in glibc 2.29, but Vercel uses glibc 2.26. Therefore, when running `bun install` on Vercel, the function would fail, and `bun install` would not handle that failure.

The fix was to implement a `posix_spawn`-like polyfill for Linux.

## New: `performance.mark()` APIs

You can now use [user-timings](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/User_timing) APIs, which include `performance.mark()` and `performance.measure()`. This is useful for measuring the performance of your code.

```js
performance.mark("start");
while (true) {
  // ...
}
performance.mark("end");
performance.measure("task", "start", "end");
```

You can also use the [`PerformanceObserver`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver) API to listen for performance events.

```js
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === "mark") {
      console.log(entry); // { name: "start", startTime: 0 }
    } else if (entry.entryType === "measure") {
      console.log(entry); // { name: "task", startTime: 0, duration: 1000 }
    }
  }
});

observer.observe({ entryTypes: ["mark", "measure"] });
```

Thanks to [@gvilums](https://github.com/gvilums) for submitting a PR to add this to Bun, and thanks to the [WebKit](https://webkit.org/) team for their implementation of these APIs.

## New: `child_process` support for extra pipes

You can now pass extra pipes to `child_process` functions. This is useful for passing data between processes. For example, you can pass a pipe to a child process, and then write to that pipe from the parent process.

{% codetabs %}

```js#parent.js
import { spawn } from "node:child_process";

const child = spawn(process.argv0, ["child.js"], {
  stdio: ["inherit", "inherit", "inherit", "pipe"],
});

const pipe = child.stdio[3];
pipe.on("data", (data) => {
  console.log(data.toString()); // "hello!"
});
```

```js#child.js
import { createWriteStream } from "node:fs";

const stream = createWriteStream(null, { fd: 3 });
stream.on("ready", () => {
  stream.write("hello!");
});
```

{% /codetabs %}

### Coming soon: Playwright support

These changes were necessary to support [Playwright](https://playwright.dev/), which uses extra pipes to communicate with the browser process. However, there is still one [outstanding PR](https://github.com/microsoft/playwright/pull/28875) that needs to be merged to get Playwright working with Bun.

Thanks to [@nektro](https://github.com/nektro) for implementing this missing API.

## New: Brotli support for `fetch`

You can now use `fetch` to make requests with the `br` encoding. This is useful for making requests to servers that support Brotli compression.

```js
const response = await fetch("https://example.com", {
  headers: {
    "Accept-Encoding": "br",
  },
});
```

We also changed brotli support to be statically-linked in Bun, instead of dynamically-linked. This fixed issues with certain Linux distros and older macOS releases that did not have the nessary libraries.

## New: `toBeEmptyObject` and `toContainKeys` matchers

You can now use `expect().toBeEmptyObject()` to check if an object is empty.

```js
expect({}).toBeEmptyObject();
expect({ a: 1 }).not.toBeEmptyObject();
```

You can also use `expect().toContainKeys()` or `expect().toContainAnyKeys()` to check if an object contains certain keys.

```js
expect({ a: 1, b: 2 }).toContainKeys(["a", "b"]);
expect({ a: 1, b: 2 }).not.toContainKeys(["c"]);
```

```js
expect({ foo: "bar" }).toContainAnyKeys(["foo", "baz"]);
expect({ foo: "bar" }).not.toContainAnyKeys(["baz"]);
```

Thanks to [@coratgerl](https://github.com/coratgerl) for implementing this feature.

## New: 15% to 400% faster `Buffer.concat`

Using `Buffer.concat` is now 15% to 400% faster, depending on the size of the buffers being concatenated.

{% raw %}

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">In the next version of Bun<br><br>Buffer.concat gets 15% - 400% faster, depending on the input size. <a href="https://t.co/hdC1mqhF51">pic.twitter.com/hdC1mqhF51</a></p>&mdash; Jarred Sumner (@jarredsumner) <a href="https://twitter.com/jarredsumner/status/1744320845856821392?ref_src=twsrc%5Etfw">January 8, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
{% /raw %}

We also fixed a bug where `Buffer.concat` would crash when concatenating a large number of buffers. This was caused by an out-of-memory error not being handled correctly.

## New: 10% to 15% faster `new Headers(object)`

Using `new Headers(object)` and `new URLSearchParams(object)` with an object is now 10% to 15% faster.

{% raw %}

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">In the next version of Bun<br><br>new Headers(myObject) gets 10% faster <a href="https://t.co/JLSeFDvq8A">pic.twitter.com/JLSeFDvq8A</a></p>&mdash; Jarred Sumner (@jarredsumner) <a href="https://twitter.com/jarredsumner/status/1743903845850415465?ref_src=twsrc%5Etfw">January 7, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
{% /raw %}

## Fixed: `console.table` width using emojis

In Bun v1.0.21, we added support for [`console.table`](https://developer.mozilla.org/en-US/docs/Web/API/console/table_static). However, we did not properly handle emojis, and the table would be misaligned if there were emojis or unicode characters in the table. This has been fixed by using the official Unicode [dataset](https://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt) to determine the width of each character.

| Before (Bun v1.0.21)                 | After (Bun v1.0.22)                  |
| ------------------------------------ | ------------------------------------ |
| ![](https://i.imgur.com/YWY643E.png) | ![](https://i.imgur.com/1pyKiDC.png) |

Thanks to [@otgerrogla](https://github.com/otgerrogla) for implementing `console.table`, and following up to fix this bug.

## New: `argv` and `execArgv` options for `worker_threads`

Bun did not support the `argv` and `execArgv` options for `worker_threads`. This has been fixed.

{% codetabs %}

```js#index.js
import { Worker } from "node:worker_threads";

const worker = new Worker("./worker.js", {
  argv: ["--foo", "bar"],
  execArgv: ["--inspect"],
});

worker.on("message", (data) => {
  console.log(data);
  // { argv: [ "--foo", "bar" ], execArgv: [ "--inspect" ] }
});
```

```js#worker.js
postMessage({
  argv: process.argv,
  execArgv: process.execArgv,
});
```

{% /codetabs %}

Thanks to [@otgerrogla](https://github.com/otgerrogla) for fixing this missing functionality.

## Fixed: Binding to `0.0.0.0` would bind to IPv6 as well

There was a bug where `createServer` would bind to both IPv4 and IPv6 when binding to `0.0.0.0`. This has been fixed thanks to [@Hanaasagi](https://github.com/Hanaasagi).

## Fixed: HTTP method casing in `node:http`

In Bun v1.0.10, we introduced a bug where the `PURGE` and `OPTIONS` headers were not being properly transformed to uppercase. This caused problems with Fastify and CORS pre-flight requests. This has been fixed thanks to [@asomethings](https://github.com/asomethings).

## Fixed: Partial consume on `BufferList`

There was a bug where multiple, partial consumes on `BufferList` would not increment the `offset` properly. This caused `cbor` to not work properly, and has been fixed thanks to [@hborchardt](https://github.com/cbor).

## Fixed: `bun build --compile` with `compiled://` URL

We fixed a bug where `bun build --compile` would not work with `compiled://` URLs. This has been fixed by changing `compiled://` URLs to use a special prefix that Bun recognizes.

## New: `assert.doesNotMatch`

You can now use [`assert.doesNotMatch`](https://nodejs.org/api/assert.html#assertdoesnotmatchstring-regexp-message) to check if a string does not match a regular expression.

```js
assert.doesNotMatch("I will not match", /match/);
```

Thanks to [@markusn](https://github.com/markusn) for implementing this missing API.

## Thanks to 22 contributors!

Thank you to all the contributors to this release of Bun, including the new 13 contributors who submitted their first pull request!

- [aarvinr](https://github.com/@aarvinr)
- [asomethings](https://github.com/@asomethings)
- [coratgerl](https://github.com/@coratgerl)
- [guest271314](https://github.com/@guest271314)
- [gvilums](https://github.com/@gvilums)
- [Hanaasagi](https://github.com/@Hanaasagi)
- [hborchardt](https://github.com/@hborchardt)
- [huseeiin](https://github.com/@huseeiin)
- [jakeg](https://github.com/@jakeg)
- [Jarred-Sumner](https://github.com/Jarredd-Sumner)
- [jdalton](https://github.com/@jdalton)
- [karmabadger](https://github.com/@karmabadger)
- [knightspore](https://github.com/@knightspore)
- [lino-levan](https://github.com/lino-levan)
- [markusn](https://github.com/@markusn)
- [MatricalDefunkt](https://github.com/@MatricalDefunkt)
- [morisk](https://github.com/@morisk)
- [nektro](https://github.com/@nektro)
- [otgerrogla](https://github.com/@otgerrogla)
- [paperclover](https://github.com/@paperclover)
- [sitiom](https://github.com/@sitiom)
- [ThatOneCalculator](https://github.com/@ThatOneCalculator)
- [twlite](https://github.com/@twlite)

You can also read the [full changelog](https://github.com/oven-sh/bun/compare/bun-v1.0.21...bun-v1.0.22).
