pwshub.com

Bun v1.1.25

Bun v1.1.25 is here! This release fixes 42 bugs (addressing 470 👍). Support for node:cluster and V8's C++ API. Faster WebAssembly on Windows with OMGJIT. 5x faster S3 uploads with @aws-sdk/client-s3, Worker in standalone executables, and more Node.js compatibility improvements and bug fixes.

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

To install Bun

curl

curl -fsSL https://bun.sh/install | bash

powershell

powershell -c "irm bun.sh/install.ps1|iex"

docker

docker run --rm --init --ulimit memlock=-1:-1 oven/bun

To upgrade Bun

node:cluster support

Bun now supports the node:cluster API.

This allows you to run a pool of Bun workers that share the same port, enabling higher throughput and utilization on machines with many CPU cores. This is great for load balancing in production environments.

Here's an example of how it works:

  • The primary worker spawns n child workers (usually equal to the number of CPU cores)
  • Each child worker listens on the same port (using reusePort)
  • Incoming HTTP requests are load balanced across the child workers
import cluster from "node:cluster";
import http from "node:http";
import { cpus } from "node:os";
import process from "node:process";

if (cluster.isPrimary) {
  console.log(`Primary ${process.pid} is running`);

  // Start N workers for the number of CPUs
  for (let i = 0; i < cpus().length; i++) {
    cluster.fork();
  }

  cluster.on("exit", (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} exited`);
  });
} else {
  // Incoming requests are handled by the pool of workers
  // instead of the primary worker.
  http
    .createServer((req, res) => {
      res.writeHead(200);
      res.end("hello world\n");
    })
    .listen(3000);

  console.log(`Worker ${process.pid} started`);
}

This works with the node:http APIs, as well as the Bun.serve() API.

import cluster from "node:cluster";
import { cpus } from "node:os";

if (cluster.isPrimary) {
  for (let i = 0; i < cpus().length; i++) {
    cluster.fork();
  }
} else {
  Bun.serve({
    port: 3000,
    fetch(request) {
      return new Response(`Hello from Worker ${process.pid}`);
    },
  });
}

Note that currently, reusePort is only effective on Linux. On Windows and macOS, the operating system does not load balance HTTP connections as one would expect.

Thanks to @nektro for implementing this feature!

Initial V8 C++ API support

Bun now supports V8's public C++ API, which unblocks packages like cpu-features to work in Bun.

This is notable change because Bun is not built on top of V8 like Node.js. Instead, Bun is built on top of JavaScriptCore, the JavaScript engine that powers Safari.

That means we had to implement our own C++ translation layer between V8's APIs and JavaScriptCore.

src/bun.js/bindings/v8/V8String.cpp

#include "v8.h"
#include "V8Primitive.h"
#include "V8MaybeLocal.h"
#include "V8Isolate.h"

namespace v8 {

enum class NewStringType { /* ... */ };

class String : Primitive {
public:
    enum WriteOptions { /* ... */ };

    BUN_EXPORT static MaybeLocal<String> NewFromUtf8(Isolate* isolate, char const* data, NewStringType type, int length = -1);
    BUN_EXPORT int WriteUtf8(Isolate* isolate, char* buffer, int length = -1, int* nchars_ref = nullptr, int options = NO_OPTIONS) const;
    BUN_EXPORT int Length() const;

    JSC::JSString* localToJSString()
    {
        return localToObjectPointer<JSC::JSString>();
    }
};
}

This is difficult engineering work. JavaScriptCore and V8 represent JavaScript values differently. V8 uses a moving, concurrent garbage collector with explicit handle scopes whereas JavaScriptCore uses a non-moving concurrent garbage collector that scans stack memory (sort of like an implicit handle scope).

Before, if you tried to import a package that used these APIs, you would get an error like this:

console.log(require("cpu-features")());
dyld[94465]: missing symbol called
fish: Job 1, 'bun index.ts' terminated by signal SIGABRT (Abort)

Now, packages like cpu-features can be imported and just work in Bun.

$ bun index.ts
{
  arch: "aarch64",
  flags: {
    fp: true,
    asimd: true,
    // ...
  },
}

This is just the start of support for V8's internal APIs. If your package runs into an area of the V8 API that we have not yet implemented, you'll receive an error that directs you to upvote an issue on GitHub.

Why support V8's internal APIs?

We did not originally intend to support these APIs, but decided to after we found that many popular packages depend on these APIs, such as:

In this release, only cpu-features is supported from the list above, but we're working on improving support so all of these packages and more just work in Bun.

Thanks to @190n for implementing this feature!

5x faster S3 uploads with @aws-sdk/client-s3

We fixed a bug in our node:http client implementation and that made uploading to S3 5x faster.

Worker in standalone executables

Bun's single-file standalone executables now support bundling Worker and node:worker_threads.

main.ts

console.log("Hello from main thread!");

new Worker("./my-worker.ts");

my-worker.ts

console.log("Hello from another thread!");

To compile a standalone executable with a worker, pass the entry points to bun build --compile:

bun build --compile ./main.ts ./my-worker.ts

This will bundle my-worker.ts and main.ts as separate entry points in the resulting executable.

Embedding files in standalone executables without importing

You can now embed files in standalone executables without an explicit import statement, if you want.

bun build --compile ./main.ts ./public/**/*.png

Usually, you'd have to import the file to use it:

import logo from "./public/icons/logo.png" with {type: "file"};

But, sometimes you want to import a large number of files that may need to programmatically be referenced.

Bun.embeddedFiles

The new Bun.embeddedFiles API lets you see a list of all embedded files in a standalone executable.

import { embeddedFiles } from "bun";

for (const file of embeddedFiles) {
  console.log(file.name); // "logo.png"
  console.log(file.size); // 1234
  console.log(await file.bytes()); // Uint8Array(1234) [...]
}

This combines all non-javascript entry points and assets into a single array of Blob objects sorted by name.

Relative imports for embedded files in standalone executables

You can now reference runtime-known imports of embedded files using relative paths in standalone executables.

function getWasmFilePath(file: string) {
  return require.resolve(`./${file}.wasm`);
}

const wasmFile = getWasmFilePath("my-wasm-file");
console.log(wasmFile); // "./my-wasm-file.wasm"

Previously, this was only supported with statically-analyzable imports that are knonwn at build time. Now, you can do this with any embedded file.

Faster WebAssembly on Windows with OMGJIT

WebAssembly on Windows now supports JavaScriptCore's optimized Just-In-Time compiler (JIT) called OMGJIT.

In the next version of Bun

JavaScriptCore's optimizing WebAssembly JIT "OMGJIT" is enabled on Windows, making this wasm hashing benchmark 20% faster pic.twitter.com/8qhKVS4E6z

— Bun (@bunjavascript) August 17, 2024

Thanks to Ian Grunert for shipping this feature in WebKit!

Node.js compatiblity improvements

execa now works

We fixed a bug where Bun was not properly supporting setMaxListeners() for EventTarget. This affected packages like execa, which would error out with undefined is not a function.

import { execa } from "execa";

const { stdout } = await execa`echo "test"`;

If you experienced an error that looks like this, it has now been fixed:

91 |    const controller = new AbortController();
92 |    setMaxListeners(Number.POSITIVE_INFINITY, controller.signal);
      ^
TypeError: undefined is not a function
      at node:events:101:30
      at spawnSubprocessAsync (/node_modules/execa/lib/methods/main-async.js:92:2)
      at execaCoreAsync (/node_modules/execa/lib/methods/main-async.js:26:32)
      at index.mjs:3:26

Fixed: Connection hangs with node:net after destroy()

We fixed a bug where calling destroy() on a TCP connection, didn't always properly exit the process, since the event loop was still active. This would sometimes cause packages like postgres to hang indefinitely.

import net from "node:net";

const server = net.createServer((socket) => {
  socket.on("connect", (data) => {
    socket.destroy();
    // This would destroy the connection,
    // but the event loop would still be active
  });
});

server.listen(3000);

Fixed: node:net.Socket's ref and unref this

The ref and unref methods on node:net.Socket were not returning the this value.

Now, they return this.

Thanks to @nektro for fixing this bug!

Bugfixes

Fixed: TextEncoderStream yielded the wrong type

In Bun v1.1.23, we introduced support the the TextEncoderStream API. We fixed a bug where the chunks from the stream were Buffer objects instead of Uint8Array objects.

const response = await fetch("https://example.com");
const body = response.body.pipeThrough(new TextEncoderStream());

for await (const chunk of body) {
  console.log(chunk);
  // Before: Buffer
  // Now: Uint8Array
}

Fixed: crash with escaped backticks in Bun's shell

We fixed a crash in Bun's shell that would not properly handle escaped backticks.

import { $ } from "bun";

console.log(await $`cd \`find -name dir\``.text());

Thanks to @zackradisic for fixing this bug!

Fixed: JIT crash with TextEncoder

We fixed a bug where if TextEncoder was JIT'd after being run millions of times, it would crash. This was due to a bug in Bun's generated code for enabling the JIT on a function.

Fixed: Crash in jest.fn and mock()

A crash that could occur when calling functions on a jest.fn or mock() object with an unexpected this value has been fixed.

Fixed: Crash in IPC

When a child process exited before the parent process received a message, a crash could occur in some cases.

This has been fixed, thanks to @cirospaciari.

Fixed: console.log a File's name

When you use the web File constructor to create a Blob, the name of the file was not being included in the output of console.log.

Input:

console.log(new File(["hello world"], "hello.txt"));

New:

File (11 bytes) {
  name: "hello.txt",
  lastModified: 1724218333315
}

Previously:

Fixed: rare crash in websocket server

A rare crash that could potentially occur when a long amount of time has passed since the server has called a callback and the ServerWebSocket object has been garbage collected has been fixed.

Thank you to 11 contributors!

Source: bun.sh

Related stories
1 week ago - Fixes 130 bugs (addressing 250 👍). `bun pm pack`, faster `node:zlib`. Static routes in Bun.serve(). ReadableStream support in response.clone() & request.clone(). Per-request timeouts. Cancel method in ReadableStream is called. `bun run`...
9 hours ago - This release fixes 40 bugs (addressing 51 👍). Compile & run C from JavaScript. 30x faster path.resolve. Named pipes on Windows. Several Node.js compatibility improvements and bugfixes.
1 month ago - Fixes 72 bugs (addressing 63 👍). 30% faster fetch() decompression, New --fetch-preconnect flag, improved Remix support, Bun gets 4 MB smaller on Linux, bundle packages excluding dependencies, many bundler fixes and node compatibility...
1 month ago - Fixes 79 bugs (addressing 93 👍). Express is now 3x faster in Bun, ES modules load faster on Windows, 10% faster Bun.serve() at POST requests, source maps in `bun build --compile`. Memory usage reductions to `--hot`, Bun.serve(), and...
1 month ago - Support for `TextEncoderStream` and `TextDecoderStream`, 50% faster `console.log(string)`, support for `Float16Array`, Node.js<>Bun IPC on Windows, truncate large arrays in `console.log()`, and many more bug fixes and Node.js...
Other stories
1 hour ago - Ubuntu 24.10 ‘Oracular Oriole’ is released on October 13th, and as you’d expect from a new version of Ubuntu, it’s packed with new features. As a short-term release, Ubuntu 24.10 gets 9 months of ongoing updates, security patches, and...
3 hours ago - Did you know that CSS can play a significant role in web accessibility? While CSS primarily handles the visual presentation of a webpage, when you use it properly it can enhance the user’s experience and improve accessibility. In this...
4 hours ago - Design thinking workshops are your key to turning big problems into clear solutions. In this blog, I share how to run them efficiently and keep your team aligned. The post How to run a design thinking workshop appeared first on LogRocket...
4 hours ago - New memory-optimized X8g instances offer up to 3 TiB DDR5 memory, 192 vCPUs, and 50 Gbps network bandwidth, designed for memory-intensive workloads like databases, analytics, and caching with unparalleled price/performance and efficiency.
4 hours ago - Gain indispensable data engineering expertise through a hands-on specialization by DeepLearning.AI and AWS. This professional certificate covers ingestion, storage, querying, modeling, and more.