Bun

Bun v1.1.8


Ashcon Partovi ยท May 10, 2024

Bun v1.1.8 is here! This release fixes 54 bugs (addressing 184 ๐Ÿ‘). Support for process.on("uncaughtException") and process.on("unhandledRejection"), JSON.parse gets faster, Brotli support in node:zlib, [Symbol.dispose] in Bun APIs, fixes lots of crashes on Windows, and many other bugfixes.

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

Previous releases

  • v1.1.7 fixes 28 bugs (addressing 11 ๐Ÿ‘). Glob workspace names in bun install. Asymmetric matcher support in expect.extends() equals. bunx --version. Bugfixes to JSX transpilation, sourcemaps, cross-compilation of standalone executables, bun shell, RegExp, Worker on Windows, and Node.js compatibility improvements.
  • v1.1.6 fixes 10 bugs (addressing 512 ๐Ÿ‘ reactions). We've implemented UDP socket support & node:dgram. DataDog and ClickHouseDB now work. We've fixed a regression in node:http from v1.1.5. There are also Node.js compatibility improvements and bugfixes.
  • 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

New: Support for process.on("uncaughtException") and process.on("unhandledRejection")

Bun now supports the process.on("uncaughtException") and process.on("unhandledRejection") events, which allow you to handle uncaught exceptions and unhandled promises in a more graceful way.

process.on("uncaughtException", (error) => {
  console.error("Uncaught exception:", error);
});

process.nextTick(() => {
  throw new Error("Oops!");
});

This also works for unhandled promises, which is useful for handling errors in asynchronous code.

process.on("unhandledRejection", (reason, promise) => {
  console.error("Unhandled rejection:", reason);
});

await 42;
throw new Error("Oops!");

This should resolve issues with various npm packages, like puppeteer, that would clean up resources if an unhandled exception occurred.

Thanks to @gvilums for adding this feature!

New: Brotli support for node:zlib

Bun now implements the Brotli APIs in the node:zlib module, including BrotliCompress(), BrotliDecompress(), brotliCompress(), brotliDecompress(), and more!

import { brotliCompressSync, brotliDecompressSync } from "node:zlib";

const compressed = brotliCompressSync("Hello, world!");
console.log(compressed.toString("hex"));
// => 0b068048656c6c6f2c20776f726c642103

const decompressed = brotliDecompressSync(compressed);
console.log(decompressed.toString("utf8"));
// => Hello, world!

You can also use Brotli streams with the zlib module.

import { createBrotliCompress } from "node:zlib";

const compressor = createBrotliCompress();
compressor.write("Hello, world!");
compressor.end();

const compressed = compressor.read();
console.log(compressed.toString("hex"));
// => 0b068048656c6c6f2c20776f726c642103

Fixes a regression with axios

Adding support for Brotli also fixed a regression with axios, so it should now work again in Bun.

Thanks to @nektro for adding this feature!

New: Support for [Symbol.dispose] in Bun APIs

Bun now supports the [Symbol.dispose] property on various APIs, including Bun.spawn, Bun.serve, Bun.connect, and Bun.listen. This allows you to define a variable with the using syntax, which is defined by the TC39 proposal for Explicit resource management in JavaScript.

import { serve } from "bun";

{
  using server = serve({
    port: 0,
    fetch(request) {
      return new Response("Hello, world!");
    },
  });

  doStuff(server);
}

function doStuff(server) {
  // ...
}

In this example, the server is automatically closed when the server variable goes out of scope, even if an exception is thrown. This is useful for ensuring that resources are properly cleaned up, especially in tests.

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

test("able to spawn a process", async () => {
  using subprocess = spawn({
    cmd: [process.execPath, "-e", "console.log('Hello, world!')"],
    stdout: "pipe",
  });

  const stdout = new Response(subprocess.stdout).text();
  expect(stdout).resolves.toBe("Hello, world!");
});

Thanks to @paperdave for implementing this feature!

Faster: JSON.parse

Fixed: Illegal instruction on Windows

We fixed a bug in the build script of Bun that caused Windows dependencies to be built with the wrong CPU flags. This caused Illegal instruction errors with older CPUs on Windows.

This bug resolved over 18 GitHub issues and was caught thanks to Bun's new crash reporter.

Fixed: Crash with console.log using a %i format string

We fixed a bug where console.log could crash using a %i format string that was out of bounds for the number of arguments.

console.log("Hello %i %i", [1, 2, 3, 4]);
// Before: <panic>
// Now: 'Hello NaN %i'

Thanks to @paperdave for fixing this bug!

Fixed: Several workspace dependency not found errors

We fixed various issues that would cause bun install to fail with workspace dependency not found errors.

  • The first bug was caused by adding a new workspace dependency to a workspace that did not define a version property in its package.json.

  • The second bug was caused by manually adding a workspace dependency to the packages property in the workspace package.json, then attempting to run bun install.

We are still working on making workspaces better in Bun. If you still experience problems with workspaces, please file an issue.

Fixed: Crash with console.table when being called repeatedly

We fixed a bug were the reference counting of strings using console.table was being incorrectly calculated, which could cause a crash.

for (let i = 0; i < 50; i++) {
  console.table([{ n: 8 }]);
}

Thanks to @dylan-conway for fixing this bug!

Fixed: Bug with createReadStream with a file descriptor and offset

We fixed a bug where using createReadStream with a file descriptor and start offset would cause the offset to be ignored.

import { openSync, createReadStream, writeSync } from "node:fs";

const fd = openSync("hello.txt", "w+");
const stream = createReadStream("", { fd: fd, start: 2 });

stream.on("data", (chunk) => {
  // Before: "Hello, world!"
  // Now: "llo, world!"
});

writeSync(fd, "Hello, world!");

Thanks to @gvilums for fixing this bug!

Fixed: confirm() did not work on Windows

Bun implements the confirm() Web API, which prompts the terminal for a confirmation message. We were not properly handling Windows line endings, so the confirmation would never betrue.

if (confirm("Are you sure?")) {
  console.log("Yes!");
} else {
  console.log("No!");
}

This was fixed thanks to @rcaselles.

Fixed: Bug with os.cpus() for some CPUs

We fixed a bug where os.cpus() would throw an error when the CPU string was too long.

import { cpus } from "node:os";

console.log(cpus());
// Before: <error: Failed to get cpu information>
// Now: [ { model: "Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz", ... } ]

This was fixed thanks to @dylan-conway.

Fixed: Missing agent property on ClientRequest

We fixed a bug where the agent property was missing on the ClientRequest class.

import { request } from "node:http";

const req = request("https://example.com");
console.log(req.agent);
// Before: undefined
// Now: <Agent>

Thanks to @nektro for fixing this bug!

Fixed: Redirecting stdout from Bun.spawn() to Bun.serve() was not working

There was a bug where redirecting stdout from Bun.spawn() to Bun.serve() was not working. This has now been fixed.

import { spawn, serve } from "bun";

const server = serve({
  port: 0,
  async fetch(req) {
    const { stdout } = spawn({
      cmd: [process.execPath, "-e", 'console.write("Hello, world!")'],
      stdout: "pipe",
    });

    return new Response(stdout);
  },
});

const response = await fetch(server.url);
console.write(await response.text());
server.stop(true);

Fixed: onread not working in node:net

We added support for the onread event in the node:net module, which allows you to listen for incoming data on a socket.

import { connect } from "node:net";

const socket = connect({
  host: "example.com",
  port: 80,
  onread: {
    buffer: Buffer.alloc(1024),
    callback(size, buffer) {
      console.log("onread:", size);
    },
  },
});

socket.write("GET / HTTP/1.1\r\n\r\n");
// Before: <nothing>
// Now: onread: 504

Thanks to @gvilums for fixing this bug!

Fixed: Crash in InlineCacheCompiler

A crash that could occur when a function was accessed in certain ways and subsequently garbage collected after some minutes of activity has been fixed. This crash was an upstream issue in the JavaScriptCore engine that began in Bun v1.1.7 and has now been resolved. Some users reported this crash occurring while using Next.js.

Fixed: Better stub for node:inspector

Bun does not support the node:inspector module, since it depends on the Chrome DevTools protocol, which is similar but not the same as WebKit's protocol.

Previously, Bun would throw an unimplemented error when trying to use inspector.url(). Now, we have changed it to return undefined, which is the allowed behavior according to the Node.js documentation.

Some npm packages, like typedoc, use this API for feature detection. With these changes, those packages will now work with Bun.

import { url } from "node:inspector";
// ...
const isDebugging = () => !!url();

Thanks to @Electroid for making this better!

Thank you to 12 contributors!