Bun v1.0.24

Jarred Sumner ยท January 20, 2024

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

This release fixes 9 bugs and adds Bun Shell, a fast cross-platform shell with seamless JavaScript interop. Fixes a socket timeout bug, a potential crash when socket closes, a Node.js compatibility issue with Hapi, a process.exit bug, and bun install binlinking bug, bun inspect regression, and bun:test expect().toContain bug.

Previous releases

  • v1.0.23 fixes 40 bugs (addressing 194 ๐Ÿ‘ reactions). import & embed sqlite databases in Bun, Resource Management ('using' TC39 stage3) support, bundler improvements when building for Node.js, bugfix for peer dependency resolution, semver bugfix, 4% faster TCP on linux, Node.js compatibility improvements and more"
  • 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.
  • 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.

To install Bun:

curl -fsSL https://bun.sh/install | bash
npm install -g bun
brew tap oven-sh/bun
brew install bun
docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

To upgrade Bun:

bun upgrade

Bun Shell

The Bun Shell is an experimental embedded language & interpreter in Bun that allows you to run cross-platform shell scripts in JavaScript & TypeScript.

import { $, file } from "bun";

const resp = await fetch("https://example.com");

const stdout = await $`gzip -c < ${resp}`.arrayBuffer();

// as a file()
await $`ls *.js > ${file("output.txt")}`;

// or as a file path string, if you prefer:
await $`ls *.js > output.txt`;
await $`ls *.js > ${"output.txt"}`;

// Get the output as text
const combined = await $`cat ./1.txt ./2.txt`.text();

// iterate over the output line-by-line
for await (let line of $`cat ./1.txt ./2.txt`.lines()) {

Read more about the Bun Shell in the blog post or read the docs.

Fixed: socket timeout behavior

In Node.js, when a net.Socket times out, it emits a timeout event. In Bun, we emitted the timeout event, but we also closed the socket. This is not the behavior of Node.js and is not what users expect, so we fixed it. This also applies to Bun.connect() and Bun.listen().

Fixed: Potential crash when socket closes

A crash that could occur when frequently connecting and disconnecting from sockets (usually a database client) has been fixed

Node.js compatiblity improvements for "perf_hooks"

Previously, Hapi (@hapi/hapi) was not working in Bun because the perf_hooks.eventLoopUtilization function was not defined. Bun now defines it, and returns empty values for all metrics which unblocks Hapi.

Fixed: process.exit threw "exitCode is not a number" in some cases

process.exit(eval("1.234 - 0.234")) would throw an error in Bun, but not in Node.js. This has been fixed.

The bug was in how Bun was reading the exitCode argument within the process.exit function. JavaScriptCore's JSValue representation of 1.234 - 0.234 represents it as a 64-bit floating point number, even though it is technically just the signed 32-bit integer 1. Bun's code was specifically checking if the representation was a signed 32 bit integer instead of being any integer number, which caused the error. The fix was to check if the value was an integer number instead of a signed 32-bit integer.

This bug impacted Prisma CLI, which uses process.exit to exit the process with a non-zero exit code when an error occurs.

When a symlink already existed but pointed to a path which no longer exited, bun install would not overwrite the symlink. This has been fixed, thanks to @dylan-conway.

Fixed: regression with fully-qualified URL in bun --inspect

When using bun --inspect with a fully-qualified URL, the URL was not being parsed correctly. This has been fixed, thanks to @Electroid.

Fixed: expect().toContain("") behaved incorrectly

A bug where bun:test's implementation of expect(a).toContain("") behaved inconsistently with Jest has been fixed, thanks to @DontBreakAlex.

Fixed: path.parse edgecase

Given the string path.parse('.prettierrc'), the path.parse function in Bun would return different results in Bun and Node.js.

Now Bun returns the same result as in Node.js, thanks to @Aarav-Juneja.

Fixed: hang in recursive console.log

A hang when a function logs inside of console.* has been fixed, thanks to @LukasKastern.

Thanks to 14 contributors!