Bun

Bun v1.1.19


Dylan Conway · July 12, 2024

Bun v1.1.19 is here! This release fixes 54 bugs (addressing 248 👍). JavaScript gets faster on Windows. Raspberry Pi 4 support returns. _auth support in .npmrc. bun install preserves package.json indentation. aws-cdk-lib support. Memory leak fixes in new Response(request) and fs.readdir. Several reliability improvements. Statically linked UCRT on Windows.

We're hiring systems engineers in San Francisco to build the future of JavaScript!

Previous releases

  • v1.1.18 Fixes 55 bugs (addressing 493 👍). Support for npmrc. Improved constant folding & enum inlining. Improved console.log output for functions. Fixes patching dependencies in workspaces. Fixes several bugs in bun install when linking binaries. Fixes a crash in dns.lookup, and normalizes DNS errors to better match Node. Fixes an assertion failure in Bun.escapeHTML. Upgrades JavaScriptCore.
  • v1.1.17 Fixes 4 bugs. Fixes a crash in bun repl. Makes fs.readdirSync 5% faster on macOS in small directories. Fixes "ws" module not calling the callback in "send" method. Fixes a crash when reading a corrupted lockfile in bun install. Makes macOS event loop a smidge faster.
  • v1.1.0 Bundows. Windows support is here!

To install Bun

curl
npm
powershell
scoop
brew
docker
curl
curl -fsSL https://bun.sh/install | bash
npm
npm install -g bun
powershell
powershell -c "irm bun.sh/install.ps1|iex"
scoop
scoop install bun
brew
brew tap oven-sh/bun
brew install bun
docker
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

To upgrade Bun

bun upgrade

JavaScript gets faster on Windows

This release enables WebKit's FTL JIT (Faster Than Light Just In Time Compiler) on Windows, which improves hot path performance. Previously, this JIT was only available on macOS and Linux.

Object.entries gets about 20% faster:

Runtimebenchmarktime (avg)
Bun v1.1.19Object.entries(26 keys)726 ns/iter
Bun v1.1.18Object.entries(26 keys)1'006 ns/iter
Node v22.4.1Object.entries(26 keys)1'014 ns/iter
Bun v1.1.19Object.entries(2 keys)55.99 ns/iter
Bun v1.1.18Object.entries(2 keys)114 ns/iter
Node v22.4.1Object.entries(2 keys)115 ns/iter
Node v22.4.1Object.keys(26 keys)206 ns/iter
Bun v1.1.19Object.keys(26 keys)509 ns/iter
Bun v1.1.18Object.keys(26 keys)671 ns/iter

Array.map overhead drops by about 50%:

Runtimebenchmarktime (avg)
Bun v1.1.19Array.map x 1 args31.23 ns/iter
Bun v1.1.18Array.map x 1 args58.32 ns/iter
Node v22.4.1Array.map x 1 args84.27 ns/iter
Bun v1.1.19Array.map x 2 args30.42 ns/iter
Bun v1.1.18Array.map x 2 args56.96 ns/iter
Node v22.4.1Array.map x 2 args84.87 ns/iter

And so much more. JavaScriptCore's FTL JIT is 25,000 lines of C++ -- it does a lot.

===============================================================================
 Language            Files        Lines         Code     Comments       Blanks
===============================================================================
 C Header               46         4436         2407         1264          765
 C++                    35        29919        23306         1925         4688
===============================================================================
 Total                  81        34355        25713         3189         5453

Huge thanks to @iangrunert!

Raspberry Pi 4

Bun once again supports Raspberry Pi 4. A build issue preventing Bun from running on the Raspberry Pi 4 has been fixed.

Raspberry Pi 4

1 MB smaller on Linux

We've enabled a link-time optimization that makes Bun 1 MB smaller on Linux.

Statically-linked Windows build

On Windows, Bun will now use a statically linked copy of UCRT. This means you don't need the Visual C++ runtime installed to run Bun.

bun install improvements

bun install respects package.json indentation

Space and tab indentation in package.json is now preserved when saving new dependencies with Bun.

Thanks to @dylan-conway!

bun install supports _auth in .npmrc

bun install now supports the _auth option in .npmrc files. This is useful for providing both username and password together.

.npmrc
//http://localhost:4873/:_auth=${NPM_AUTH}

Thanks to @zackradisic!

Fixed: crash with optional peer dependencies

During an install with optional peer dependencies, sometimes Bun would crash. To reproduce this crash, one would need this package.json

package.json
{
    "dependencies": {
        "a": "1.0.0",
        "b": "1.0.0",
    }
}

with these dependencies:

{
  "name": "a",
  "version": "1.0.0"
}
{
  "name": "b",
  "version": "1.0.0",
  "peerDependencies": {
    "a": "1.0.0"
  },
  "peerDependenciesMeta": {
    "a": {
      "optional": true
    }
  }
}

The crash would occur after running bun install, deleting node_modules and cache (bun pm cache rm), bumping b to a newer version that still has an optional peer dependency on a, then running bun install again with the existing lockfile.

There are more than a few steps to reproduce this crash, but it was a common issue with packages like vite or vue due to their use of optional peer dependencies.

This is now fixed, thanks to @dylan-conway!

Warn when binaries from bun install -g are not in path

When the global bin folder isn't in path, Bun will now print a warning and a suggestion to add the folder to path.

bun add v1.1.19 (18a0f05c)

installed node-gyp@10.2.0 with binaries:
 - node-gyp

warn: To run "node-gyp", add the global bin folder to $PATH:

fish_add_path "/Users/jarred/.bun/bin"

Fixed: cwd for symlinked dependency postinstall scripts on Windows

Before running a postinstall script, the cwd is set to the package directory in node_modules. When the package is a workspace, the directory in node_modules is a symlink to the workspace. On posix this is fine - the symlink is resolved and process.cwd() prints the absolute path through the project root. On Windows, the symlink is not resolved, resulting in an unexpected cwd of C:/path/to/proj/node_modules/workspace instead of C:/path/to/proj/workspace.

Now, Bun resolves these paths manually on Windows to ensure the cwd is the expected path.

Thanks to @dylan-conway!

Transpiler improvements

Improved: Comma expression folding

Bun no longer uses recursion when folding comma separated expressions in JavaScript/TypeScript, reducing the risk of stack overflow. This fixes crashes when using some libraries like aws-cdk-lib and aws-sdk.

Thanks to @paperdave!

Fixed: invalid transpilation of nested TypeScript namespace declarations

A TypeScript transpilation bug has been fixed where nested namespaces were incorrectly transpiled, resulting in exports not being available. This could happen if they were non-inlined namespaces.

export namespace Foo.Bar {
  export function bar() {
    return "hello world";
  }
}

console.log(Foo.Bar.bar()); // "hello world"

This is fixed thanks to @paperdave!

Reliability improvements

Fixed: afterEach callback running for test.todo

Previously, afterEach was running for each test.todo, causing the following code to fail. This is now fixed. test.todo will continue to trigger afterEach and beforeEach if --todo is used.

import { test, expect, afterEach } from "bun:test";

let count: number = 0;

afterEach(() => {
  count++;
});

test.todo("todo");

test("afterEach should not run for test.todo", () => {
  expect(count).toBe(0);
});

Thanks to @ThatOneBro!

Fixed: memory leak in new Request(request)

When passing a Request instance to the Request constructor, the Request constructor would leak memory. This is now fixed.

const old = new Request("https://example.com", { body: "hello!" });

// This would leak memory:
const req = new Request(old);

This was only a problem when passing a Request instance to the Request constructor. Passing a Request instance to fetch was not affected, nor was passing an object shaped like a Request instance.

Fixed: crash when sending large files with Bun.serve

When sending a large file with Bun.serve and the process is killed with process.kill or the request is aborted, Bun would sometimes crash. This has been fixed, thanks to @cirospaciari!

Fixed: crash in remapping stack frames with bun build

There was a double free on a string when using bun build --sourcemap=external --target=bun, causing a segfault.

This is now fixed, thanks to @paperdave!

Fixed: AbortSignal reliability improvement with fetch()

When cancelling a request with AbortSignal in fetch(), sometimes it wouldn't cancel for HTTPS requests until after the response had completed. This bug is now fixed. An incorrect option in our BoringSSL integration caused it to ignore TCP shutdown calls.

Thanks to @cirospaciari!

Improved: profile from bun:jsc now supports promises

In Bun v1.1.19 you will now be able to pass promises to profile.

import { profile } from "bun:jsc";
const { promise, resolve } = Promise.withResolvers();
const result = await profile(
  async function test(input: string) {
    await Bun.sleep(10).then(() => resolve(input));
  },
  1,
  "input",
);
const input = await promise;
console.log(input); // { "0": "input" }

Fixed: FormData.set settings file name incorrectly

A bug has been fixed where FormData would incorrectly set file names with .set. This code will now work as expected, thanks to @billywhizz!

using server = Bun.serve({
    port: 0,
    fetch: async req => {
        const data = await req.formData();
        const file = data.get("file");
        console.log(file.name); // foo.txt
        return new Response();
    }
})

const form = new FormData();
form.set("file", new File(["hello"], "foo.txt"));
await fetch(server.url, { method: "POST", body: form });

Node.js compatibility improvements

fs errors

This release fixes argument validation issues in node:fs.

Previously, the following code would throw a confusing error:

import { fs } from "fs";

fs.open("path");

Previous error:

bun-1.1.18.ts
1 | fs.open("path")
       ^
TypeError: path must be a string or TypedArray
 code: "ERR_INVALID_ARG_TYPE"

      at node:fs:36:26
      at open2 (node:fs:276:25)
      at path-to-file.ts:1:4

Now, the error correctly mentions the missing callback:

bun-1.1.19.ts
1 | fs.open("path")
       ^
TypeError: The "cb" argument must be of type function. Received undefined
 code: "ERR_INVALID_ARG_TYPE"

      at node:fs:2:30
      at open (node:fs:288:25)
      at path-to-file.ts:1:4

fs.write argument fix

Previously, the following input would incorrectly throw an error:

import fs from "fs";

fs.write(1, Buffer.from("hi"), 0, console.log, undefined);

Now it works as expected, consistent with Node.js.

Previously, this threw an error about a missing callback:

1 | fs.write(1, Buffer.from("hi"), 0, console.log, undefined)
       ^
TypeError: Callback must be a function
 code: "ERR_INVALID_ARG_TYPE"
      at node:fs:2:30
      at write2 (node:fs:297:27)

Fixed: memory leak in fs.readdir withFileTypes: true

When calling fs.readdir with withFileTypes: true, the path property was leaking memory while directory entries were being read. This is now fixed, thanks to @billywhizz!

Thanks to 25 contributors!