---
title: Bun v1.1.14
description: "Fixes 63 bugs (addressing 519 👍). Patch node_modules with bun patch. ORM-less object mapping in bun:sqlite. Log fetch() calls as curl commands. Node.js compatibility improvements. bun install bugfixes, bun:sqlite bugfixes, WebSocket fixes, Windows bugfixes"
date: "2024-06-19T08:02:22.120Z"
author: chloe
---

Bun v1.1.14 is here! This release fixes 63 bugs (addressing 519 👍). Patch node_modules with `bun patch`. ORM-less object mapping in `bun:sqlite`. Log all `fetch()` calls as a `curl` command. Node.js compatibility improvements. bun install bugfixes, `bun:sqlite` bugfixes, Windows bugfixes. And more.

{% callout %}
We're hiring [systems engineers](/careers) in San Francisco to build the future of JavaScript!
{% /callout %}

#### Previous releases

- [`v1.1.13`](/blog/bun-v1.1.13) fixes 97 bugs (addressing 211 👍). Reliability improvements to bun install, WebSocket server, fetch, worker_threads. worker_threads now supports eval. `URL.createObjectURL`, stack trace error location improvements, several `bun install` fixes
- [`v1.1.10`](/blog/bun-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 improvements
- [`v1.1.0`](/blog/bun-v1.1) Bundows. Windows support is here!

#### To install Bun

{% codetabs %}

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

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

```sh#powershell
$ powershell -c "irm bun.sh/install.ps1|iex"
```

```sh#scoop
$ scoop install 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
```

## `bun patch`

Bun v1.1.14 introduces a new subcommand for Bun's package manager: `bun patch`

```sh
$ bun patch <pkg>
```

Sometimes, dependencies have bugs or missing features. You could fork the package, make your changes, and publish it. But that's a lot of work for a small change. And what if you don't want to maintain a fork? What if you want to continue to receive updates from the original package, but with your changes?

`bun patch` makes it easy to modify dependencies without forking or vendoring. Changes persist into a `.patch` file which can be reviewed, shared, versioned, and reused in other projects. These `.patch` files are automatically applied on `bun install`, with the results cached in Bun's [Global Cache](https://bun.sh/docs/install/cache).

To get started, run `bun patch <pkg>` to patch a package.

```sh
$ bun patch is-even

bun patch v1.1.14

+ is-even@1.0.0

5 packages installed [3.00ms]

To patch is-even, edit the following folder:

  node_modules/is-even

Once you're done with your changes, run:

  bun patch --commit 'node_modules/is-even'

```

Internally, this clones the package in node_modules with a fresh copy of itself independent from the shared cache. This allows you to safely make edits to files in the package's directory without impacting the Global Cache.

Since we clone the package, you can test your patches locally in your project's node_modules folder. This makes it easy to iterate on your changes and verify they work as expected.

Once you're happy with your changes, run `bun patch --commit <pkg>` to save your changes.

```sh
$ bun patch --commit is-even
```

When you run `bun patch --commit is-even`, Bun:

1. Generates a patch file with your changes
2. Adds the dependency to `"patchedDependencies"` in your `package.json`
3. Saves the patch file in the root of your project under `patches/`

Patch files use the standard `diff` format, so you can review, share, and version them like any other code.

```diff#./patches/is-even@1.0.0.patch
diff --git a/index.js b/index.js
index 832d92223a9ec491364ee10dcbe3ad495446ab80..2a61f0dd2f476a4a30631c570e6c8d2d148d419a 100644
--- a/index.js
+++ b/index.js
@@ -1,14 +1 @@
-/*!
- * is-even <https://github.com/jonschlinkert/is-even>
- *
- * Copyright (c) 2015, 2017, Jon Schlinkert.
- * Released under the MIT License.
- */
-
-'use strict';
-
-var isOdd = require('is-odd');
-
-module.exports = function isEven(i) {
-  return !isOdd(i);
-};
+module.exports = (i) => (i % 2 === 0)
```

Thanks to [@zackradisic](https://github.com/zackradisic) for implementing `bun patch`!

## Better `bun:sqlite`

This release adds several improvements to Bun's builtin sqlite module `bun:sqlite`.

### ORM-less object mapping with `query.as(Class)`

`bun:sqlite` now supports mapping query results to instances of a class. This lets you attach methods, getters, and setters to query results without using an ORM.

<!-- prettier-ignore -->
```ts
import { Database } from "bun:sqlite";

const db = new Database("my.db");

class Tweet {
  id: number;
  text: string;
  username: string;

  get isMe() {
    return this.username === "jarredsumner";
  }
}

const tweets = db
  .query("SELECT * FROM tweets")
  .as(Tweet);

for (const tweet of tweets.all()) {
  if (!tweet.isMe) {
    console.log(`${tweet.username}: ${tweet.text}`);
  }
}
```

The properties don't need to be defined on the class ahead of time (it's there just to make the example easier to read) and the order of the columns in the query doesn't matter.

This is a light way to map query results to objects. Underneath, it works similarly to `Object.create`, which meanas it doesn't call constructors, run default initializers, and cannot access private fields.

The `as` method is defined on the `Statement` class, so you can use it with `get` and `all` methods. It's important to note that this is not an ORM. It doesn' manage relationships, generate SQL, or anything like that. It makes queries return a class instance instead of a plain object.

#### How it works

When you call `query.as(Class)`, Bun creates a new object with the class's prototype and assigns the query result to it.

```ts
const query = db.query("SELECT * FROM tweets").as(Tweet);

// Get the first row as a Tweet instance
const tweet: Tweet = query.get();

// Each row is a Tweet instance
const allTweets: Tweet[] = query.all();
```

### Simpler query bindings with `strict: true`

This release adds a new `strict?: boolean` option to the `Database` constructor which lets you omit the `$`, `@`, or `:` prefix when binding values to prepared statements.

```ts-diff
 import { Database } from "bun:sqlite";

 const db = new Database(":memory:", {
-  strict: false,
+  strict: true,
 });

 const query = db.query(`select $message;`);

 query.all({
-  $message: "Hello world"
+  message: "Hello world"
 });
```

When `strict: true`, queries will throw if they are missing any bindings.

To keep backwards compatibility, `strict` defaults to false. It is recommended to enable for new projects.

### Track changes with `query.run(sql)`

The `run` method on `Database` and `Statement` now returns an object with `changes` and `lastInsertRowid` properties. This makes it easier to track changes and get the last inserted row id.

```ts
import { Database } from "bun:sqlite";

const db = new Database(":memory:");

db.run(`CREATE TABLE hey ( id INTEGER, data TEXT)`);
const { changes, lastInsertRowid } = db.run(
  `insert into hey (id, data) values (1, 'foo')`,
);
console.log({
  changes, // => 1
  lastInsertRowid, // => 1
});
```

This is important when verifying that a query has made changes to the database. Previously, `run` would return `undefined`.

### BigInts with `safeIntegers: true`

When `safeIntegers` is `true`, `bun:sqlite` will return integers as `bigint` types.

```ts
import { Database } from "bun:sqlite";

const db = new Database(":memory:", { safeIntegers: true });
const query = db.query(
  `SELECT ${BigInt(Number.MAX_SAFE_INTEGER) + 102n} as max_int`,
);
const result = query.get();
console.log(result.max_int); // => 9007199254741093n
```

These integers must fit within 64-bit range. If an input exceeds that, `bun:sqlite` will throw an error.

```ts
import { Database } from "bun:sqlite";

const db = new Database(":memory:", { safeIntegers: true, strict: true });
db.run("CREATE TABLE test (id INTEGER PRIMARY KEY, value INTEGER)");

const query = db.query("INSERT INTO test (value) VALUES ($value)");

try {
  query.run({ value: BigInt(Number.MAX_SAFE_INTEGER) ** 2n });
} catch (e) {
  console.log(e.message); // => BigInt value '81129638414606663681390495662081' is out of range
}
```

Sometimes, you only wnat this behavior for specific queries. The `safeIntegers` method is available on `Statement`.

```ts
import { Database } from "bun:sqlite";

const db = new Database(":memory:", { strict: true });

const query = db.query("SELECT $value as value").safeIntegers(true);

const result = query.get({ value: BigInt(Number.MAX_SAFE_INTEGER) + 102n });
console.log(result.value); // => 9007199254741093n
```

### Fixed: query.values() with duplicate column names

A bug caused duplicate column names to be ignored when calling `query.values()`. This has been fixed.

```ts
import { Database } from "bun:sqlite";
const db = new Database();
const result = db.prepare("select 1 as id, 2 as id").values();
console.log(result);
```

Fixed:

<!-- prettier-ignore -->
```ts
[
  [ 1, 2 ]
]
```

Previously:

<!-- prettier-ignore -->
```ts
[
  [ 2 ]
]
```

This bug would most frequently occur when using JOIN.

### Fixed: `bun:sqlite` with table joins crash fixed.

A crash that sometimes occurred when joining tables with duplicate columns has been fixed. This impacts using Drizzle's driver for `bun:sqlite` and `.leftJoin`.

## bun install reliability

### Fixed: Tarballs failing to download exit with non-zero code

When a tarball failed to download, `bun install` would exited with a zero exit code. This has been fixed. When any HTTP request fails, `bun install` will now exit with a non-zero exit code so that CI systems stop the build.

### Fixed: `bun install` handling transitive folder dependencies

Sometimes packages are published to the npm registry with a `file:` dependency. Sometimes

Thanks to [@dylan-conway](https://github.com/dylan-conway) for fixing this.

### Fixed: `bun install` extracting bug fix

It is possible for a `.tar.gz` archive to contain multiple entries for the same directory (one with `./` and one without it). Bun now handles this while extracting, instead of reporting an error that the directory it's extracting to already exists.

Thanks to [@dylan-conway](https://github.com/dylan-conway) for fixing this.

### Fixed: `bun install --production` in a workspace included devDependencies

When `--production` is passed to `bun install` in a workspace, the dev dependencies of the workspace packages would be included in the install. This is no longer the case.

This also fixed an assertion failure when in this situation.

### Fixed: Not passing `npm_config_user_agent` on Windows

In order for project initialization scripts like `create-next-app` to know which package manager to use, package managers are expected to set the `npm_config_user_agent` environment variable. Bun on Windows was not always passing modified environment variables to child processes, so that has been fixed.

For example, creating a new Next.js project on Windows will properly tell Next.js to use `bun install`.

```diff
 PS> bun create next-app
 ✔ What is your project named? … my-app
 ✔ Would you like to use TypeScript? … No / Yes
 ✔ Would you like to use ESLint? … No / Yes
 ✔ Would you like to use Tailwind CSS? … No / Yes
 ✔ Would you like to use `src/` directory? … No / Yes
 ✔ Would you like to use App Router? (recommended) … No / Yes
 ✔ Would you like to customize the default import alias (@/*)? … No / Yes
 Creating a new Next.js app in D:\Projects\my-app.

-Using npm.
+Using bun.

 Initializing project with template: app-tw
```

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

## Debugging fetch()

This release adds a new environment variable to help debug network traffic when using `fetch()` or `node:http`.

When `BUN_CONFIG_VERBOSE_FETCH=1` is passed as an environment variable, Bun will log all network traffic through `fetch` and `node:http` clients.

![](https://github.com/oven-sh/bun/assets/709451/95d9ebb8-4e25-418e-b68a-a21590e55f02)

### Print fetch() as a `curl` command

When `BUN_CONFIG_VERBOSE_FETCH=curl` is set as an environment variable, Bun will print all network traffic through `fetch` and `node:http` clients as `curl` commands.

```ts
process.env.BUN_CONFIG_VERBOSE_FETCH = "curl";

await fetch("https://example.com", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ foo: "bar" }),
});
```

This prints the `fetch` request as a `curl` command to let you copy-paste into your terminal to replicate the request.

```sh
[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.1.14" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}"
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.1.14
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13

[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256
```

You can use this to debug network requests, to replicate network requests, or to inspect what different JavaScript/TypeScript tools are sending over the network without needing to wire up a proxy.

## Node.js compatibility improvements

### `node:fs/promises` functions now accept `FileHandle`

When using `node:fs/promises`, the `readFile`, `writeFile`, and `appendFile` functions accept [`FileHandle`][file-handle] objects as input.

[file-handle]: https://nodejs.org/docs/latest-v22.x/api/fs.html#class-filehandle

```ts
import { open, readFile } from 'node:fs/promises';

using file = await open("example.txt", "rw");
const contents = await readFile(file);
console.log(contents);
await writeFile(file, `New data: ${Math.random()}\n`);
```

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

### `process.env.NODE_TLS_REJECT_UNAUTHORIZED`

You can now set `process.env.NODE_TLS_REJECT_UNAUTHORIZED` at runtime to disable or enable SSL certificate verification. This is useful for testing or debugging, but should not be enabled in production.

```ts
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
await fetch("https://self-signed.badssl.com"); // no error
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "1";
await fetch("https://self-signed.badssl.com"); // throws error
```

Previously, this environment variable could only be passed at startup. Now, it can be set at runtime.

### Fixed: Hang in `node:http` / `express`

A bug impacting node:http server where `req.completed` was never set to true would cause some requests in Express to hang indefinitely. This has been fixed thanks to [@cirospaciari](https://github.com/cirospaciari)

### Fixed: `blob.type`

A race condition would sometimes make `blob.type` from `fetch` `undefined`. Thanks to [@cirospaciari](https://github.com/cirospaciari), this has now been resolved.

```ts
const blob = await fetch("https://bun.sh/logo.svg").then((res) => res.blob());
console.log("Blob type is:", blob.type);
```

### Fixed: `blob.name` is writable

You can now set the `name` property on a `Blob` object.

```ts
const blob = await fetch("https://bun.sh/logo.svg").then((res) => res.blob());
blob.name = "bun!!!!!";
console.log(blob.name); // "bun!!!!!"
```

Previously, setting `blob.name` would throw a TypeError:

```ts
1 | const blob = await fetch("https://bun.sh/logo.svg").then((res) => res.blob());
2 | blob.name = "bun!!!!!";
    ^
TypeError: Attempted to assign to readonly property.
```

### Fixed: WebSocket over SSL with large binary payloads

Previously, when sending large binary payloads over `wss://` WebSocket connections, the message might not have been sent. This was due to not calling `set_retry_write` from BoringSSL. Thanks to [@cirospaciari](https://github.com/cirospaciari) for fixing this.

### Fixed: Bun no longer crashes Windows Terminal

On Windows, the flag `ENABLE_VIRTUAL_TERMINAL_INPUT` was always enabled on the console input. Without removing this flag before exit, most shells would break (`cmd.exe` arrow keys break, Powershell would often crash, `nu` would not be able to accept new lines, etc). This flag was removed, as Bun no longer needed it set for it's input handling (`prompt()`, `node:readline`, `bun init`, etc)

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

### Fixed: WebSocket header casing inconsistent with node

Previously, using `new WebSocket` would convert all headers into lowercased text. This had some issues with some servers that expected headers to have certain casing, even though headers are meant to be case insensitive. Now, well-known headers will be normalized to their canonical form, and custom headers will retain their exact casing.

For example:

```ts
const ws = new WebSocket("ws://localhost:3000", {
  headers: {
    "Origin": "http://localhost:3000",
    "authorization": "password",
    "X-some-Other-header": "bun!",
  },
});
```

Will send these headers:

```
> Origin: http://localhost:3000
> Authorization: password
> X-some-Other-header: bun!
```

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

### Fixed: memory leak in Bun Shell

A memory leak impacting the Bun Shell has been fixed. This would cause the shell objects to never be garbage collected, preventing memory from being reclaimed.

### Fixed: Regression with error.line

A bug where `error.line` and `error.column` would return `0` has been fixed. This regression was introduced in `v1.1.13`.

### Thanks to 10 contributors!

- [@cirospaciari](https://github.com/cirospaciari)
- [@diogomdp](https://github.com/diogomdp)
- [@dylan-conway](https://github.com/dylan-conway)
- [@huseeiin](https://github.com/huseeiin)
- [@Jarred-Sumner](https://github.com/Jarred-Sumner)
- [@nektro](https://github.com/nektro)
- [@oscarfsbs](https://github.com/oscarfsbs)
- [@paperclover](https://github.com/paperclover)
- [@ShrootBuck](https://github.com/ShrootBuck)
- [@SunsetTechuila](https://github.com/SunsetTechuila)
- [@zackradisic](https://github.com/zackradisic)
