Bun

Bun v1.1.44


Ben Grant · January 16, 2025

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

This release fixes 43 bugs. You can now build frontend applications on-demand in Bun.serve(). Adds xxHash support to Bun.hash(). Adds support for reading bun.lock using import. Adds --no-install flag to bunx. Improves console.warn output. Fixes bugs in Bun's S3 client, HTMLRewriter, and node:fs compatibility improvements, and more.

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

Fullstack Dev Server

With HTML imports, you can now run your frontend and backend together in a single incredibly fast Bun.serve() HTTP server. This makes it simpler to build modern frontend applications integrated with your backend.

HTML imports

This release introduces support for importing HTML files in Bun behind the --experimental-html CLI flag. These HTML files are processed by Bun's bundler together with Bun.serve(). You can use the static option to serve these HTML files as routes. Bun.serve() bundles the frontend application with zero configuration and adds bundled assets as static routes.

import mySinglePageApp from "./index.html";
import { s3 } from "bun";

Bun.serve({
  static: {
    // the "/" route goes to
    "/": mySinglePageApp,
    // ... more html imports go here
  },

  // Enable some logging & errors
  development: true,

  async fetch(req) {
    // ... api endpoints go here
    const path = getS3Path(req); // ...
    return Response.redirect(s3.file(path).presign());
  },
});

In Bun v1.1.43, we added support for HTML entrypoints in Bun's bundler. This release builds on that to add initial support in Bun.serve() to serve HTML files as routes.

You can use HTML imports to build single-page React applications on-demand in a shared backend server.

src/backend.ts
src/frontend.tsx
public/dashboard.html
src/styles.css
src/app.tsx
src/backend.ts
import dashboard from "./public/dashboard.html";
import { serve } from "bun";

serve({
  static: {
    "/": dashboard,
  },

  async fetch(req) {
    // ...api requests
    return new Response("hello world");
  },
});
src/frontend.tsx
import "./styles.css";
import { createRoot } from "react-dom/client";
import { App } from "./app.tsx";

document.addEventListener("DOMContentLoaded", () => {
  const root = createRoot(document.getElementById("root"));
  root.render(<App />);
});
public/dashboard.html
<!DOCTYPE html>
<html>
  <head>
    <title>Dashboard</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="../src/frontend.tsx"></script>
  </body>
</html>
src/styles.css
body {
  background-color: red;
}
src/app.tsx
export function App() {
  return <div>Hello World</div>;
}

This is still pretty early - there's no hot-module reloading support yet. But we'll get there.

bunx --no-install

bunx now supports the --no-install flag, which will cause the command to only run if it has already been installed in the current path or the global prefix.

Thanks to @DonIsaac for implementing this!

Read bun.lock with import

You can now read the contents of Bun's new text-based lockfile with an import statement.

import { lockfileVersion } from "./bun.lock";

console.log(lockfileVersion);

We've also added type definitions to @types/bun so that TypeScript understands how the lockfile is structured. And, since the new lockfile is a JSONC file, we also allow importing other .jsonc files as well.

Thanks to @RiskyMH for implementing this!

xxHash support in Bun.hash

The Bun.hash namespace now includes Bun.hash.xxHash32, Bun.hash.xxHash64, and Bun.hash.xxHash3, implementing the xxHash family of fast non-cryptographic hash functions. These are suitable for applications where data must be hashed very quickly and some hash collisions are acceptable, such as integrity checks of data you trust has not been tampered with maliciously, but they should not be used for cryptographic purposes such as hashing passwords or untrusted data.

xxhash.ts
// Print a hash of stdin
const data = await new Response(Bun.stdin).arrayBuffer();
const hash: BigInt = Bun.hash.xxHash3(data);
// Format as 16 hexadecimal digits with leading zeroes
console.log(hash.toString(16).padStart(16, "0"));
cat xxhash.ts | bun xxhash.ts
aeac788911bfd3bb
xxhsum -H3 xxhash.ts # -H3 selects the xxHash3 algorithm
XXH3_aeac788911bfd3bb  xxhash.ts

Thanks to @versecafe for wiring up the Zig standard library functions to Bun!

Node.js compatibility improvements

node:dns > 90% Node.js tests passing

node:dns now passes > 90% of Node.js's own test suite.

Thanks to @heimskr for making this happen!

node:fs fixes

We've fixed several bugs and inconsistencies compared to Node.js in our node:fs implementation, improving compatibility with existing Node.js projects and packages. We also now run a large chunk of Node.js's own tests for the fs module on every commit. This works out to about +10% more of Node.js's test suite for fs passing in Bun.

Thanks to @paperclover for implementing this!

Fixed: attempt to assign to read-only property in Axios

A property in node:http was incorrectly marked as read-only, leading Axios to throw an error in certain cases. This release fixes that bug.

Fixed: crash impacting happy-dom & node:vm

A regression in Bun v1.1.43 caused a crash when using happy-dom or node:vm. This release fixes this crash and adds a test to prevent it from happening again.

Fixed: IPC with JSON serialization with Bun as the parent process

Previously, Bun would send incorrectly-formatted messages to child processes if IPC was used with serialization set to "json". Now it always sends JSON messages in this case.

Thanks to @nektro for fixing this!

Bugfixes

This release also includes a number of bugfixes.

Fixed: bun install --lockfile-only --silent printing lockfile summary

Previously, running bun install --lockfile-only --silent would still print a summary of the packages saved in the lockfile, despite the --silent option. Now the --silent option is respected.

Thanks to @DonIsaac for fixing this!

Fixed: Regression with expect.extend()

A change to our JavaScriptCore bindings in Bun v1.1.43 caused expect.extend() to ignore properties on prototype objects, causing some test matcher libraries to not work properly. This release fixes this regression.

Thanks to @pfgithub for fixing this!

Fixed: missing x-amz-acl header in S3 client

Bun's S3 client was missing the x-amz-acl header in certain cases.

Thanks to @robertshuford for fixing this!

Fixed: expect().toThrow() now matches expect().toThrow("")

In Jest & Vitest, when you run expect(a).toThrow(""), it behaves the same as expect(a).toThrow(). In bun:test, it was throwing an error. We've changed this to match Jest & Vitest so that it's a little bit easier to migrate your tests.

Thanks to @DonIsaac for fixing this!

Fixed: error handling in HTMLRewriter

A crash has been fixed in Bun's HTMLRewriter API when a JavaScript exception was thrown. Now these errors are propagated correctly.

Fixed: slicing S3 file with offset 0

Calling slice() on a file returned by Bun's S3 client would previously have no effect with an offset set to zero. Now the file is properly truncated via an HTTP range request.

Thanks to @cirospaciari for fixing this!

Fixed: Missing authorization with private npm packages

When parsing .npmrc config files, prior versions of Bun did not apply auth configuration to scoped registries if a default registry had the same hostname as the scoped registry. For instance, if you need to access private packages on npmjs.org you would set a token so that npm's servers know you are allowed to access those packages:

.npmrc
//registry.npmjs.org/:_authToken=<AUTH_TOKEN>

Since registry.npmjs.org is one of the default registries, Bun would not send the authentication token and you would not have been able to download private packages. Now the configuration options are all applied correctly.

Thanks to @robertshuford for fixing this!

More improvements

console.warn is yellow

When you console.warn an Error object, the name property is now yellow instead of red. This tells you that it was a warning and not an error.

Additionally, when the name property is "Error", it prints "warn" instead of "error" to make it clearer that it's a warning and not an error.

Consistent help message colorization

The --help messages for Bun's subcommands are now more consistent in their formatting and colorization.

Thanks to @fel1x-developer for fixing this!

Help message for bun exec --help

A bug in command-line parsing was causing bun exec --help to reuse the help message from bun run. Now it correctly prints its own help message.

Thanks to @RiskyMH for fixing this!

Updated root certificates

Bun's built-in root certificates have been updated to NSS 3.107. These are the same certificates that shipped in Firefox 134.

Thanks to @cirospaciari for implementing this!

Improved bundleDependencies support in bun publish and bun pm pack

The bundleDependencies (or bundledDependencies) option in package.json allows a package to include the source code of its dependencies in the tarball published to the registry, instead of requiring the dependencies to be downloaded separately. Bun previously recognized the array form of this option in bun pm pack and bun pm publish, which allows specifying a list of dependencies to be bundled. But we hadn't supported setting this flag to true, which is shorthand for specifying that all dependencies should be bundled. Now we do support this. We've also added support for bundling scoped packages as dependencies.

Thanks to @RiskyMH for implementing this!

Thanks to 21 contributors!