Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager — all in one.
Bun v1.0.32 fixes 13 bugs and improves Node.js compatibility. 'ws' package can now send & receive ping/pong events. util.promisify'd setTimeout setInterval, setImmediate work now. FileHandle methods have been implemented.
Previous releases
v1.0.31
fixes 54 bugs (addresses 113 👍 reactions), introducesbun --print
,<stdin> | bun run -
,bun add --trust
,fetch()
with Unix sockets, fixes macOS binary size regression, fixes high CPU usage bug in spawn() on older linux, addsutil.styleText
, Node.js compatibiltiy improvements, bun install bugfixes, and bunx bugfixesv1.0.30
fixes 27 bugs (addressing 103 👍 reactions), fixes an 8x perf regression to Bun.serve(), adds a new--conditions
flag tobun build
and Bun's runtime, adds support forexpect.assertions()
andexpect.hasAssertions()
in Bun's test runner, fixes crashes and improves Node.js compatibility.v1.0.29
fixes 8 bugs. Bun.stringWidth(a) is a ~6,756x faster drop-in replacement for the popular 'string-width' package. bunx checks for updates more frequently. Adds expect().toBeOneOf() in bun:test. Memory leak impacting Prisma is fixed. Shell now supports advanced redirects like '2>&1', '&>'. Reliability improvements to bunx, bun install, WebSocket client, and Bun Shellv1.0.28
fixes 6 bugs (addressing 26 👍 reactions). Fixes bugs impacting Prisma and Astro,node:events
,node:readline
, andnode:http2
. Fixes a bug in Bun Shell involving stdin redirection and fixes bugs inbun:test
withtest.each
anddescribe.only
.
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
Fixed: GitHub actions timeout with bun install
In Bun v1.0.31, we rewrote how a lot of I/O works in Bun in preparation for Windows support. This has led to a few regressions.
When more than 16 lifecycle scripts were invoked at the very end of the install process, bun install
could potentially hang. To prevent system instability, bun install sets a maximum number of lifecycle scripts to execute concurrently. Due to a bug, the counter which increments the number of active lifecycle scripts was never decremented. This has been fixed.
Thanks to @farreldarian for providing an easy reproduction.
Fixed: bun install --production regression
Bun v1.0.31 incorrectly changed the order of how --frozen-lockfile
and --production
flags were handled.
These flags are supposed to block installs that change the lockfile, but in v1.0.31, the install process would still occur. The exit code would still be correct (causing CI to fail), but the packages were still installed.
Now it correctly verifies the lockfile and does not install packages when --frozen-lockfile
is passed before installing packages.
We've expanded our test suite to prevent this from regressing.
Fixed: Shell hanging with || &&
In certain cases the following command would hang:
import { $ } from "bun";
await $`echo 1 && echo 1`;
This was a regression caused by our I/O rewrite. We were not closing a file descriptor. This has been fixed, thanks to @zackradisic. We have expanded our test suite to prevent this from regressing.
Fixed: Using bun shell instead of system shell
In Bun v1.0.31, we unintentionally enabled the bun shell as the package.json script runner for posix. This was only meant to be enabled for Windows. We have written tests to prevent this from happening again.
We've also added the --shell
flag that lets you opt-in to using either the "bun"
shell or the "system"
shell:
bun --shell=bun run my-package-json-script
Fixed: import.meta.url query string parameters
Bun was returning the encoded query string params in import.meta.url
instead of the decoded query string params.
For the following code:
import './test?param=value'
console.log(import.meta.url);
Previously, Bun would return the following incorrect string:
bun-1.0.31 ./index.mjs
file:///Users/jarred/test.mjs%3Fparam=value
Now Bun returns the correct string:
bun ./index.mjs
file:///Users/jarred/test.mjs?param=value
Thanks to @paperdave for fixing this.
Fixed: Subprocess.kill(undefined)
The argument-coercion code for Bun.spawn().kill has been tweaked to match the behavior of Node.
Previously, this snippet would hang forever:
import { spawn } from "bun";
const proc = spawn({
cmd: ["sleep", "infinity"],
});
proc.kill(undefined);
Now undefined
will coerce to the equivalent of not passing it any arguments -- SIGTERM
. Similarly, null
, ""
, false
coerce to SIGTERM
. This aligns the behavior with Node's child_process.kill and honestly feels more like JavaScript.
Node.js compatiblity improvements
This release also includes a few Node.js compatiblity improvements
"ws" module can send & receive ping
and pong
The "ws"
WebSocket client & server can now send and receive "ping"
and "pong"
events when using Bun.
bun ping.mjs
Server is listening
Ping received on server side hello
Pong received on client side hello
Pong received on client side hello
bun-1.0.31 ping.mjs # Before
Server is listening
Pong received on client side hello
node ping.mjs # Node, for comparison
Server is listening
Ping received on server side hello
Pong received on client side hello
Pong received on client side hello
import WebSocket, { WebSocketServer } from "ws";
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", (ws) => {
ws.on("ping", (data) => {
console.log("Ping received on server side", data.toString());
ws.pong(data);
});
});
// test client
const ws = new WebSocket("ws://localhost:8080");
ws.on("pong", (data) => {
console.log("Pong received on client side", data.toString());
});
ws.on("open", () => {
ws.ping(Buffer.from("hello"));
});
// listen for the server
wss.on("listening", () => {
console.log("Server is listening");
});
FileHandle read & write methods
The Node FileHandle
class implementation in Bun is implemented more correctly. You can call .read
or .write
and it returns the expected result instead of just a number.
We've also fixed a bug that could cause it to not call close
on the file descriptor when it should have.
Thanks to @eventualbuddha for their help with this
util.promisify + setTimeout, setInterval, setImmediate
When using util.promisify
on timers in Bun, they now behave like they do in Node.js. This includes:
setTimeout
setInterval
setImmediate
import { promisify } from "util";
const setTimeoutAsync = promisify(setTimeout);
await setTimeoutAsync(1000);
// await Bun.sleep(1000)
Windows support is close
We are close to shipping Windows support with Bun v1.1. Once Bun for Windows passes 95% of Bun's test suite, we will announce the release date.
Bun for Windows currently passes 92.51% of Bun's test suite
— Bun (@bunjavascript) March 12, 2024
████████████░ 92.51%