---
title: "Bun v0.5"
description: Support for npm workspaces, DNS lookups, database drivers, and lots of improvements to bun install.
date: "2023-01-18T18:10:45Z"
author: ashcon
thumbText: v0.5.0
---

{% callout %}
We're hiring [C/C++ and Zig engineers](/careers) to build the future of JavaScript!
{% /callout %}

Bun v0.5 is packed with new features including npm `workspaces`, `Bun.dns`, and support for `node:readline`. There's improved compatibility with `node:tls` and `node:net` so several database drivers now work in Bun for the first time, including Postgres.js, `mysql2`, `node-redis`, and others. Bun also continues to get faster and more stable &mdash; `Buffer` instantiation is 10x faster, `crypto.createHasher()` is 50x faster, and `bun install` got dozens of bugfixes.

```bash
# Install Bun
curl https://bun.sh/install | bash

# Upgrade to latest release of Bun
bun upgrade
```

## Workspaces in `package.json`

Bun now supports [`workspaces`](https://docs.npmjs.com/cli/v9/using-npm/workspaces?v=true#description) in `package.json`, and it's fast. Bun installs the [Remix](https://github.com/remix-run/remix) monorepo in about 500ms on Linux.

- 28x faster than `npm install`
- 12x faster than `yarn install` (v1)
- 8x faster than `pnpm install`

![](https://user-images.githubusercontent.com/709451/212829600-77df9544-7c9f-4d8d-a984-b2cd0fd2aa52.png)

### What are workspaces?

Workspaces make it easy to develop complex software as a _monorepo_ consisting of several independent packages. To try it, specify a list of sub-packages in the `workspaces` field of your `package.json`; it's conventional to place these sub-packages in a directory called `packages`.

```json
{
  "name": "my-project",
  "version": "1.0.0",
  "workspaces": ["packages/a", "packages/b"]
}
```

{% callout %}
Bun doesn't support globs for workspace names yet, but this is coming soon!
{% /callout %}

This has a couple major benefits.

- **Code can be split into logical parts.** If one package relies on another, you can simply add it as a dependency with `bun add`. If package `b` depends on `a`, `bun install` will symlink your local `packages/a` directory into the `node_modules` folder of `b`, instead of trying to download it from the npm registry.
- **Dependencies can be de-duplicated.** If `a` and `b` share a common dependency, it will be _hoisted_ to the root `node_modules` directory. This reduces redundant disk usage and minimizes "dependency hell" issues associated with having multiple versions of a package installed simultaneously.

## `Bun.dns` and `node:dns`

Bun can now resolve domain names using the built-in `Bun.dns` API. At the moment, `Bun.dns` exposes a single function: `lookup`.

```js
import { dns } from "bun";

const records = await dns.lookup("example.com", { family: 4 });
console.log(records); // [{ address: "93.184.216.34" }]
```

We've also added a [minimal](https://github.com/oven-sh/bun/issues/1744) implementation of Node.js' [`node:dns`](https://nodejs.org/api/dns.html#dns) that uses `Bun.dns` under the hood. It's powered by [c-ares](https://c-ares.org/) and non-blocking `getaddrinfo` on MacOS.

```js
import { resolve4 } from "node:dns/promises";

const records = await resolve4("example.com");
console.log(records); // [ "93.184.216.34" ]
```

## Sockets using `node:tls` and `node:net`

Bun now supports the creation of sockets using [`net.connect()`](https://nodejs.org/api/net.html#netconnect) and [`tls.connect()`](https://nodejs.org/api/tls.html#tlsconnectoptions-callback). This unblocks several database driver libraries. A handful of representative examples:

Connect to Postgres in Bun using **[Postgres.js](https://github.com/porsager/postgres)** by [@porsager](https://github.com/porsager):

```js
import postgres from "postgres";

const sql = postgres();
const [{ version }] = await sql`SELECT version()`;

console.log(version); // "PostgreSQL 14.2 ..."
```

Connect to MySQL in Bun using **[`mysql2`](https://github.com/sidorares/node-mysql2)** client by [@sidorares](https://github.com/sidorares):

```js
import { createConnection } from "mysql2/promise";

const connection = await createConnection({
  host: "localhost",
  user: "root",
  database: "test",
});

const [rows] = await connection.execute("SELECT 1+2 AS count");
console.log(rows); // [{ count: 3 }]
```

Connect to Redis from Bun using the official [Node.js client](https://github.com/redis/node-redis):

```js
import { createClient } from "redis";

const client = createClient();
await client.connect();

await client.set("key", "Hello!");
const value = await client.get("key");

console.log(value); // "Hello!"
```

## Support for `node:readline`

Bulding CLI tools should be much easier now that Bun supports the [`node:readline`](https://nodejs.org/api/readline.html#readline) module.

```ts
import * as readline from "node:readline/promises";

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: true,
});

const answer = await rl.question("How fast is Bun from 1 to 10?\n");
if (parseInt(answer) > 10) {
  console.log("Good answer!");
}
```

Running this script yields:

```bash
$ bun readline.ts
How fast is Bun from 1 to 10?
> 11
Good answer!
```

## Custom `headers` in `WebSocket`

A [long-standing](https://github.com/whatwg/websockets/issues/16) feature request on the `WebSocket` [spec](https://github.com/whatwg/websockets) is the ability to set custom headers when opening a WebSocket. While this hasn't yet landed in the WebSocket standard, Bun now implements it. This allows users to customize the headers used for the `WebSocket` client [handshake request](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#client_handshake_request).

```ts
const ws = new WebSocket("ws://localhost/chat", {
  headers: {
    Authorization: "...",
  },
});
```

## Improvements to `bun wiptest`

While `bun wiptest` is still a work in progress, we continue to increase Bun's compatibility with Jest.

### `test.skip()`

You can use [`test.skip()`](https://jestjs.io/docs/api#testskipname-fn) to skip unwanted tests.

```js
import { describe, test, expect } from "bun:test";

describe("fetch()", () => {
  test.skip("can connect to localhost", async () => {
    const response = await fetch("http://localhost");
    expect(response.ok).toBe(true);
  });

  test("can connect to example.com", async () => {
    const response = await fetch("http://example.com");
    expect(response.ok).toBe(true);
  });
});
```

When you skip a test, it will appear as grayed out in the test output.

![bun wiptest output](https://user-images.githubusercontent.com/3238291/213013552-ec093bff-f070-46cb-a365-5f548346dd04.png)

### `expect(fn).toThrow()`

You can use [`expect(fn).toThrow()`](https://jestjs.io/docs/expect#tothrowerror) to catch expected errors.

```ts
import { test, expect } from "bun:test";

test("catch error", async () => {
  expect(() => {
    throw new Error();
  }).toThrow();
});
```

### `describe` labels are included in the output

Previously, nested `describe` labels were not included in the test runner output. Thanks to [@ethanburrell](https://github.com/ethanburrell), this has been fixed.

Before:

```js
✓ outer > my test
```

After:

```js
✓ outer > inner > my test
```

Test file:

```ts
import { describe, test } from "bun:test";

describe("outer", () => {
  describe("inner", () => {
    test("my test", () => {});
  });
});
```

## Performance boosts

### 10x faster `new Buffer()`

Previously, the `Buffer` implementation in Bun was using [`Object.setPrototypeOf()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf#syntax) to create each new instance. Eliminating this bottleneck makes it 10x faster to instantiate a small [`Buffer`](https://nodejs.org/api/buffer.html#buffer) in Bun.

![10x faster Buffer](https://user-images.githubusercontent.com/3238291/213013338-8b6c4e3c-3855-44cc-855e-3bfd455fc464.png)

### 50x faster `crypto.createHash()`

Previously, Bun was using a pure JavaScript implementation of [`crypto.createHash()`](https://nodejs.org/api/crypto.html#cryptocreatehashalgorithm-options). Now it's implemented using native code from [BoringSSL](https://github.com/boringssl/boringssl), yielding a 50x speed improvement.

## Support for `HTTPS_PROXY`

Bun will now recognize the `HTTPS_PROXY`, `HTTP_PROXY`, and `NO_PROXY` enviroment variables when making outgoing HTTP requests, which includes [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) and `bun install`. These variables allow you to specify a proxy to forward, or not forward, certain HTTP requests and are useful when running Bun within a corporate firewall.

```sh
export HTTPS_PROXY="http://proxy.example.com:8080"
export NO_PROXY="localhost,noproxy.example.com"
```

If you want to learn more about these variables, GitLab wrote a nice [explainer](https://about.gitlab.com/blog/2021/01/27/we-need-to-talk-no-proxy/).

## Module resolution changes

There are two changes to module resolution that may impact a few packages.

1. Bun no longer checks the [`browser`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#browser) property in `package.json`. This is because some packages would disable Node.js functionality, which is not what we want for Bun.
2. For better Node.js & npm compatibility, Bun's JavaScript runtime now reads the `"node"` export condition in package.json [`exports`](https://nodejs.org/api/packages.html#exports).

The order Bun's JavaScript runtime reads package.json `"exports"` conditions is:

```js
["bun", "worker", "module", "node", "browser", "default"];
```

This means that if a package has a `"node"` export condition, it will be used instead of the `"default"` or `"browser"` export condition.

## Changelog

While we continue to add new features to Bun, we're still focused on improving stability and fixing bugs. This release fixes a number of issues

### Fixes to `bun install`

Several bugs with Bun's package manager are fixed in this release, mostly by [@alexlamsl](https://github.com/alexlamsl). Thanks Alex!

{% table %}

---

- [`#1664`](https://github.com/oven-sh/bun/pull/1664)
- Previously, scoped and private packages configured with `bun install` would have a registry of `localhost`, which made very little sense. We've fixed this and private registries will now default to the default registry if not specified, which is usually `registry.npmjs.org`

---

- [`#1667`](https://github.com/oven-sh/bun/pull/1667)
- Typically, npm clients are supposed to pass the `npm-auth-type` header, but `bun install` wasn't. We've fixed this and now `bun install` will pass the `npm-auth-type` header

---

- [`a345efd`](https://github.com/oven-sh/bun/commit/a345efd270bcd19672b13b363d287354113b7aba)
- In some CI environments, like Vercel, linking `node_modules/.bin` would fail because the `/proc` filesystem (used to resolve absolute file paths) wasn't mounted. We've fixed this by falling back to `fchdir` and `getcwd` when `/proc/fd` is not available

---

- [`385c81d`](https://github.com/oven-sh/bun/commit/385c81d67be14abaaa938c0d7d46acd90d714392)
- A crash sometimes happened when running `bun add <package>` if the `"dependencies"` list went from empty to not empty in a `package.json`

<!-- ---
Note: this only impacted canary builds, not the latest release

- [`97ec866f`](https://github.com/oven-sh/bun/commit/97ec866f8523b50f242f0873ca5e9796dce54ad2)
- Fix `OutOfMemory` on `bun install` -->

---

- [`#1665`](https://github.com/oven-sh/bun/pull/1665)
- Use `npm` as default registry when scopes are configured

---

- [`#1671`](https://github.com/oven-sh/bun/pull/1671)
- Fix logging verbosity in `bun install`

---

- [`#1799`](https://github.com/oven-sh/bun/pull/1799)
- Fix lifecycle script execution in `bun install`

---

{% /table %}

### New APIs

{% table %}

---

- [`6260aaa`](https://github.com/oven-sh/bun/commit/6260aaac5fc5be7296be1414bc06977df168ec07)
- Implements [`crypto.scrypt()`](https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback) and more [`node:crypto`](https://nodejs.org/api/crypto.html#crypto) APIs

---

- [`d726a17`](https://github.com/oven-sh/bun/commit/d726a17aca6a0b7e98ee86c193158e7860bb0834)
- Implements `Bun.RIPEMD160`

---

- [`940ecd0`](https://github.com/oven-sh/bun/commit/940ecd05a8a3a1f0326256148a93306b71936c1e)
- Implements [`process.uptime()`](https://nodejs.org/api/process.html#processuptime) and [`process.umask()`](https://nodejs.org/api/process.html#processumaskmask)

---

- [`85eda20`](https://github.com/oven-sh/bun/commit/85eda2058755261bf5ac64a3d82112d7bad5419c)
- Implements `Bun.CryptoHasher`

---

- [`#1727`](https://github.com/oven-sh/bun/pull/1727)
- Implements [`expect().toThrow()`](https://jestjs.io/docs/expect#tothrowerror)

---

- [`#1659`](https://github.com/oven-sh/bun/pull/1659)
- Implements [`Buffer.{swap16,swap32,swap64}`](https://nodejs.org/api/buffer.html#bufswap16) — [@malcolmstill](https://github.com/malcolmstill)

---

- [`c18165b`](https://github.com/oven-sh/bun/commit/c18165b30fdb7cae91ce22d2a0f80ac2636e8544)
- Adds support for `ttl: true` in [`Bun.listen()`](https://github.com/oven-sh/bun#bunlisten--bunconnect---tcptls-sockets)

---

- [`734b5b8`](https://github.com/oven-sh/bun/commit/734b5b89da07fa074ea1c2a1013f32a56fc58637)
- Adds a `closeActiveConnections` parameter to `Server.stop()` and `Socket.stop()`

---

- [`8e9af05d`](https://github.com/oven-sh/bun/commit/8e9af05d)
- Changes [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) to accept URLs with `http` or `https` protocol

{% /table %}

### Additional fixes

{% table %}

---

- [`#1670`](https://github.com/oven-sh/bun/pull/1670)
- Fix incorrect `206 Partial Content` response

---

- [`#1674`](https://github.com/oven-sh/bun/pull/1674)
- Fixes a bug where `console.log({ name: "" })` would print incorrect formatting

---

- [`3d60b87`](https://github.com/oven-sh/bun/commit/3d60b870ee0d206d79eb4dda22dec7da55d91184)
- Fixes [`ReadableStream.pipeTo()`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/pipeTo)

---

- [`#1689`](https://github.com/oven-sh/bun/pull/1689)
- Fixes `bun wiptest` not waiting for async lifecycle hooks

---

- [`#1700`](https://github.com/oven-sh/bun/pull/1700)
- Fixes lingering processes with [`Bun.listen()`](https://github.com/oven-sh/bun#bunlisten--bunconnect---tcptls-sockets) and [`Bun.connect()`](https://github.com/oven-sh/bun#bunlisten--bunconnect---tcptls-sockets)

---

- [`#1705`](https://github.com/oven-sh/bun/pull/1705) [`#1730`](https://github.com/oven-sh/bun/pull/1730)
- Fixes the `connectError` callback not being invoked with [`Bun.listen()`](https://github.com/oven-sh/bun#bunlisten--bunconnect---tcptls-sockets)

---

- [`#1695`](https://github.com/oven-sh/bun/issues/1695)
- Fixes a transpiler bug that affected `@tensorflow/tfjs-backend-wasm` — [@theoparis](https://github.com/theoparis)

---

- [`#1716`](https://github.com/oven-sh/bun/issues/1716)
- Fixes [`TextDecoder`](https://nodejs.org/api/util.html#class-utiltextdecoder) being exported as [`TextEncoder`](https://nodejs.org/api/util.html#class-utiltextencoder) (oops!) — [@torbjorn-kvist](https://github.com/torbjorn-kvist)

---

- [`#1734`](https://github.com/oven-sh/bun/pull/1734)
- Fixes unhandled [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) rejections not causing an error exit code

---

- [`fadd1c0`](https://github.com/oven-sh/bun/commit/fadd1c0152ebce389f7d8fa0c297208cd71ff5c0)
- Fixes when [`Bun.connect()`](https://github.com/oven-sh/bun#bunlisten--bunconnect---tcptls-sockets) would not reject on connection error

---

- [`2392e48`](https://github.com/oven-sh/bun/commit/2392e48e9da65dbecdfa9b16446c739c7618e5a1)
- Fixes when an uncaught error in a [`describe`](https://jestjs.io/docs/api#describename-fn) block would exit `bun wiptest`

---

- [`88ffdc5`](https://github.com/oven-sh/bun/commit/88ffdc5fec9d2f99e891fc6a282c940f08428cfb)
- Fixes a transpiler bug with `export default class implements`

---

- [`#1800`](https://github.com/oven-sh/bun/pull/1800)
- Fixes [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) not accepting a `status` under 2xx

---

- [`7dd28bb`](https://github.com/oven-sh/bun/commit/7dd28bbdd99b31cc88abe4b309ed52aff64be9c2)
- Fixes an issue where [`Bun.which()`](https://github.com/oven-sh/bun#bunwhich--find-the-path-to-a-binary) would inadvertently detect a directory on macOS

---

- `—`
- Fix various bugs and improved compatibility with [Node-API](https://nodejs.org/api/n-api.html): [`59655d0`](https://github.com/oven-sh/bun/commit/59655d0587c58db1babd4438827e0323698ca3d8) [`f79301c`](https://github.com/oven-sh/bun/commit/f79301c620cc25b97008e424e1f974b749f5bc69) [`994e58b`](https://github.com/oven-sh/bun/commit/994e58b5ea29532ade0e1a517284af4645a39a98) [`c505f17`](https://github.com/oven-sh/bun/commit/c505f172b84f5359aa186513f3ef7d6394bfc7b2) [`02f0212`](https://github.com/oven-sh/bun/commit/02f0212cbd8e834d16057d0eaf9b35eef4954866) [`d54e23c`](https://github.com/oven-sh/bun/commit/d54e23ca33cc95199a58d958abf990d9a6e1eb26) [`59655d0`](https://github.com/oven-sh/bun/commit/59655d0587c58db1babd4438827e0323698ca3d8) [`f79301c`](https://github.com/oven-sh/bun/commit/f79301c620cc25b97008e424e1f974b749f5bc69)

{% /table %}

## Contributors

Thank you to everyone who contributed to Bun v0.5!

- [@Vexu](https://github.com/Vexu) for helping upgrade Bun to the latest version of [Zig](https://ziglang.org/)
- [@alexlamsl](https://github.com/oven-sh/bun/commits?author=alexlamsl&since=2022-12-22&until=2023-01-17) for `npm` workspaces, `net.Socket`, improvements to `bun install`, and many _many_ fixed bugs
- [@ThatOneBro](https://github.com/oven-sh/bun/commits?author=ThatOneBro&since=2022-12-22&until=2023-01-17) for `node:readline`
- [@colinhacks](https://github.com/oven-sh/bun/commits?author=colinhacks&since=2022-12-22&until=2023-01-17) for introducing canary builds at `bun-types@canary`
- [@cirospaciari](https://github.com/oven-sh/bun/commits?author=cirospaciari&since=2022-12-22&until=2023-01-17) for implementing `HTTP_PROXY` support
- [@srh](https://github.com/oven-sh/bun/commits?author=srh&since=2022-12-22&until=2023-01-17), [@lucifer1004](https://github.com/oven-sh/bun/commits?author=lucifer1004&since=2022-12-22&until=2023-01-17), [@u9g](https://github.com/oven-sh/bun/commits?author=u9g&since=2022-12-22&until=2023-01-17), [@eltociear](https://github.com/oven-sh/bun/commits?author=eltociear&since=2022-12-22&until=2023-01-17), [@jiaz](https://github.com/oven-sh/bun/commits?author=jiaz&since=2022-12-22&until=2023-01-17), [@malcolmstill](https://github.com/oven-sh/bun/commits?author=malcolmstill&since=2022-12-22&until=2023-01-17), and [@ethanburrell](https://github.com/oven-sh/bun/commits?author=ethanburrell&since=2022-12-22&until=2023-01-17) for contributing to Bun
