Bun v1.0.18 fixes 27 bugs (addressing 28 ๐ reactions). A hang impacting create-vite & create-next & stdin has been fixed. Lifecycle scripts reporting "node" or "node-gyp" not found has been fixed. expect().rejects works like Jest now, and more bugfixes.
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:
v1.0.13
- Fixes 6 bugs (addressing 317 ๐ reactions). 'http2' module & gRPC.js work now. Vite 5 & Rollup 4 work. Implements process.report.getReport(), improves support for ES5 'with' statements, fixes a regression in bun install, fixes a crash when printing exceptions, fixes a Bun.spawn bug, and fixes a peer dependencies bugv1.0.14
-Bun.Glob
, a fast API for matching files and strings using glob patterns. It also fixes a race condition when extracting dependencies duringbun install
, improves TypeScript module resolution innode_modules
, and makes error messages easier to read.v1.0.15
- Fixes 23 bugs (addressing 117 ๐ reactions),tsc
starts 2x faster. StableWebSocket
client, syntax-highlighted errors, cleaner stack traces, add custom test matchers withexpect.extend()
+ additional expect matchers.v1.0.16
- Fixes 49 bugs (addressing 38 ๐ reactions). Concurrent IO for Bun.file & Bun.write gets 3x faster and now supports Google Cloud Run & Vercel, Bun.write auto-creates the parent directory if it doesn't exist,expect.extend
inside of preload works,napi_create_object
gets 2.5x faster, bugfix for module resolution impacting Astro v4 and p-limit, console.log bugfixesv1.0.17
- Fixes 15 bugs (addressing 152 ๐ reactions). bun install postinstall scripts run for top 500 packages,bunx supabase
starts 30x faster thannpx supabase
,bunx esbuild
starts 50x faster thannpx esbuild
and bugfixes to bun install
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: Hang when reading from process.stdin
A bug where Bun.stdin.stream()
or process.stdin
would sometimes hang after the first read has been fixed, thanks to @paperdave.
This bug impacted many packages, including create-vite
and create-next-app
. While it prompts for user input, the terminal would freeze at the second prompt.
This was caused by two bugs related to our implementation of process.stdin
, which is built on top of Bun.stdin.stream()
:
- We previously called
cancel
on theReadableStream
input, closing the stream and preventing the ability to recieve new data. The fix is to usereleaseLock
instead. - A bug where after calling
releaseLock
, Bun would think the stream is still "in use", which would keep the process alive forever.
This has been fixed, thanks to @paperdave.
Fixed: Lifecycle scripts running in the wrong working directory
A bug where lifecycle scripts would sometimes run in the wrong working directory has been fixed. This bug was fixed by @dylan-conway.
Fixed: Lifecycle scripts reporting command not found "node" or "node-gyp"
Yesterday in Bun v1.0.17, we enabled lifecycle scripts for the top 500 packages on npm. While we did plenty of testing ourselves, we missed a few cases that were reported by users.
For example, what happens if node-gyp
was not installed?
bun install
node-gyp rebuild
Command not found: node-gyp
That's no good. We've fixed this. Now, Bun will symlink node-gyp
into running bunx node-gyp
if node-gyp
is not installed (which will lazily auto-install node-gyp).
Or what if a lifecycle script you're using depends on node
, but you're running in Docker and the container does not have node
installed?
bun install
node install.js
Command not found: node
That's not good either. Now Bun will symlink node
into running bun
if node
is not installed.
These have been fixed, thanks to @dylan-conway.
Symlinking node
to bun
works better
Bun will automatically symlink node
to bun
when it is not available to ensure scripts that expect node
to exist still work. However, Bun's CLI is very different from Node's, so when running a command like node build
or node install
, it is expected to find a file like build.js
, not invoke a bundler or package manager.
Previously:
ln -s $(which bun) node && chmod +x node
./node build
bun build v1.0.18 (a648ed9e)
error: Missing entrypoints. What would you like to bundle?
Usage:
$ bun build <entrypoint> [...<entrypoints>] [...flags]
To see full documentation:
$ bun build --help
Now:
./node build
Hello! (Bun 1.0.18)
const isBun = typeof Bun !== 'undefined';
const name = isBun ? "Bun" : "Node";
const version = isBun ? Bun.version : process.version;
console.log(`Hello! (${name} ${version})`)
Thanks to @paperdave.
Reflinks on Linux
Reflinks are copy-on-write copies of files. They make it faster to copy files. macOS has supported reflinks since APFS was released in 2017. Linux has supported reflinks with brtfs and more recently more filesystems have added support for reflinks.
Bun already used copy_file_range
on Linux to make copying files faster, but some hypervisors (like gVisor) disable this system call. Now Bun will try to use ioctl_ficlone
, which is a lower-level system call that internally does something very similar to copy_file_range
. ioctl_ficlone
is overall less well-supported than copy_file_range
, but it's a useful fallback when copy_file_range
is unavailable.
When copy_file_range
is disabled but ioctl_ficlone
is available, you will notice a speed improvement to:
bun install
fs.copyFile
,fs.copyFileSync
fs.cp
,fs.cpSync
To force the usage of ioctl_ficlone
, you can pass constants.COPYFILE_FICLONE_FORCE
as the flags
argument to fs.copyFile
or fs.cp
:
import { copyFileSync, constants } from "fs";
copyFileSync("src/index.js", "dest/index.js", constants.COPYFILE_FICLONE_FORCE);
This will throw an error if ioctl_ficlone
is not available.
Fixed: Wildcard tsconfig path not including suffix
A bug where wildcard tsconfig.json
paths
would fail to resolve due to the suffix not being added has been fixed
error: Cannot find module "@faasjs/bar" from ".../test/js/bun/resolve/resolve-test.js"
Thanks to @james-elicx for fixing this.
Fixed: expect().rejects.toThrow
works more like Jest
In Jest, expect().toThrow
requires you pass a function to call. With expect().rejects.toThrow
, they let you simply pass in the rejecting promise. Bun did not support this case.
The following test now passes in bun:test
:
test("rejects to octopus", async () => {
const rejection = Promise.reject(new Error("octopus"));
await expect(rejection).rejects.toThrow("octopus");
});
Thanks to @paperdave for fixing this.