---
title: Bun v1.0.36
description: "Fixes 13 bugs. Adds support for `fs.openAsBlob` and `fs.opendir`, fixes edgecase in bun install with multiple `bin` entries in `package.json`, fixes `bun build --target bun` encoding, fixes bug with process.stdin & process.stdout, fixes bug in http2, fixes bug with .env in bun run, fixes various Bun shell bugs and improves Node.js compatibility."
date: "2024-03-29T07:03:02.451Z"
author: ashcon
draft: false
---

> Bun is an incredibly fast JavaScript runtime, bundler, transpiler, and package manager &mdash; all in one.

Bun v1.0.36 fixes 13 bugs. Adds support for `fs.openAsBlob` and `fs.opendir`, fixes edgecase in bun install with multiple `bin` entries in `package.json`, fixes `bun build --target bun` encoding, fixes bug with process.stdin & process.stdout, fixes bug in http2, fixes bug with .env in bun run, fixes various Bun shell bugs and improves Node.js compatibility.

[Bun v1.1](https://www.youtube.com/watch?v=yXTFOeGly9o) (Bundows) is coming April 1st.

#### Previous releases

- `v1.0.35` fixed a regression from Bun v1.0.34
- [`v1.0.34`](/blog/bun-v1.0.34) fixes 7 bugs, bunx uses less memory, bun install gets faster on Docker & WSL, a conflicting devDependency hoisting bug is fixed, a cyclical CommonJS & ESM import crash is fixed, cross-mount fs.cp & fs.copyFile get 50% faster on Linux, and reliability improvements for bun install & bun's runtime.
- [`v1.0.33`](/blog/bun-v1.0.33) fixes 2 bugs, including a bug with the mv command in Bun Shell and in node:crypto creating & verifying signatures
- [`v1.0.32`](/blog/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.

#### To install Bun:

{% codetabs %}

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

```sh#npm
$ npm install -g bun
```

```sh#brew
$ brew tap oven-sh/bun
$ brew install bun
```

```sh#docker
$ docker pull oven/bun
$ docker run --rm --init --ulimit memlock=-1:-1 oven/bun
```

{% /codetabs %}

#### To upgrade Bun:

```sh
$ bun upgrade
```

### Node.js compatibility improvements

## New: `fs.openAsBlob`

Bun now supports the recently added [`fs.openAsBlob()`](https://nodejs.org/api/fs.html#fsopenasblobpath-options) API, which allows you to open a file as a Blob. This returns the same underlying `Blob` as `Bun.file`.

```js
import { openAsBlob } from "node:fs";

const blob = await openAsBlob("hello.txt");
console.log(await blob.text()); // "Hello, world!"
```

## New: `fs.opendir`

We also added support for [`fs.opendir()`](https://nodejs.org/api/fs.html#fsopendirpath-options-callback), which allows you to open a directory and read its contents.

```js
import { opendir } from "node:fs";

const dir = await opendir(".");
for await (const dirent of dir) {
  console.log(dirent.name); // "hello.txt", "world.txt"
}
```

## Fixed: Hang piping process.stdin to process.stdout

When at least 16 KB was piped to process.stdout, the process would sometimes hang. This has been fixed.

## Fixed: Crash in http2

A crash that could occur when using the `http2` client has been fixed. This crash was related to unimplemented HTTP2 features.

## Fixed: Readable.toWeb(process.stdin)

The `Readable.toWeb()` function was not working correctly when reading from `process.stdin`. This has been fixed.

Now `Readable.toWeb(process.stdin)` is effectively the same as `Bun.stdin.stream()`.

## Fixed: Regression using `process.stdout.moveCursor()`

A regression in Bun v1.0.34 caused `process.stdout.moveCursor()` to throw `ReferenceError: Can't find variable: readline`. This has been fixed.

## Fixed: TextDecoder error missing `code` property

When decoding an invalid UTF-8 string with `TextDecoder`, the error object would not have a `code` property. The Web API doesn't return a `code` property for invalid UTF-8 strings, but Node.js does. For compatiblity, we now return the same `code` property as Node.js.

This fixes a bug blocking `@angular/cli new` from running using Bun.

## Fixed: non-blocking fs.readv & fs.writev

The node:fs APIs `fs.readv` and `fs.writev` were running in a blocking manner. This has been fixed. We now enqueue the readv & writev functions to the threadpool when their `sync` versions are not called.

## Fixed: Edgecase with multiple `bin` entries in `package.json`

Previously, there was a bug when:

1. exactly one version of a package had a `bin` entry in the NPM Registry API
2. all other versions did not have a `bin` entry
3. `bin` object had multiple entries

This bug caused `bun install` to fail to link the binaries properly.

```json#package.json
{
  "bin": {
    "a": "bin",
    "b": "bin",
  }
}
```

Thanks to [@dylan-conway](https://github.com/dylan-conway) for fixing this issue.

## Fixed: missing `terminate` method in `ws` server

The `ws` polyfill in Bun was missing the `terminate` method on the WebSocketServer's WebSocket instance. This has been fixed.

Thanks to [@paperclover](https://github.com/paperclover) for fixing this issue.

### Runtime improvements

## File descriptor leak prevention mechanism

POSIX defaults file descriptors to be inherited by child processes. This frequently causes file descriptor leaks in all sorts of ways. Bun has always used the `O_CLOEXEC` flag to prevent file descriptors from being inherited, but there were cases where this was not enough.

On modern Linux kernels, Bun now uses the `close_range` system call to prevent file descriptors from being inherited without the O_CLOEXEC flag. This is a much more reliable way to prevent file descriptor leaks.

On macOS, Bun exclusively uses posix_spawn to spawn child processes which has an equivalent mechanism to prevent file descriptor leaks which makes this harder to happen in the first place.

## Restore stdin/stdout to their original state on SIGINT/SIGTERM

Previously, Bun would not always restore stdin/stdout to their original state on SIGINT/SIGTERM. This has been fixed.

## Non-blocking TTY reads

On POSIX, Bun now reads from stdin in a non-blocking manner. Normally, this would cause the other end of the pipe to also be non-blocking, but we have a workaround (thanks to reading some code from libuv). We use [`ttyname_r`](https://man7.org/linux/man-pages/man3/ttyname_r.3.html) to open the TTY as a non-blocking file descriptor without affecting the other end of the pipe.

## Fixed: Crash using `Bun.escapeHTML`

We fixed a crash where specific input could crash `Bun.escapeHTML`, which was caused by an off-by-one bug.

Thanks to Querijn Voet for reporting this issue.

## Fixed: Edgecase with WebSocket handshake

A bug in our `WebSocket` client implementation could cause non-101 status codes to be treated as a WebSocket upgrade request. This bug was not known to ever exist in the wild, but we fixed it anyway.

## Fixed: potential file descriptor redirection bug in Bun.spawn

A bug that could cause redirecting `stdin`, `stdout`, or `stderr` led to Bun closing the file descriptors before the child process finished starting. This bug was caused by misunderstanding how the `dup2` libc function works. When `dup2` receives the same file descriptor as the destination, it does nothing. Now when redirecting the same file descriptor, Bun will instead remove the `O_CLOEXEC` flag from the file descriptor which allows the child process to inherit the file descriptor. This bug only impacted linux, and was more difficult to reproduce than just inheriting file descriptors.

## Fixed: incorrect .env propagation in `bun run`

A regression caused `.env` files to be loaded unexpectedly when using `bun run` before the script is run. This regression has been fixed and we've improved our test suite to prevent this from occurring again.

## Shell (Bun.$) stability improvements

We fixed various bugs and regressions with the Bun shell, including:

- A race condition where the shell would hang.
- A possible crash when the subprocess exited before the event loop was ready.
- A possible crash when stdin was over 128kb in size.
- When spawning a subprocess that uses interactive mode, user input would not be sent to the subprocess. This affected packages like `@inquirer/prompts`.

{% codetabs %}

```js#shell.js
import { $ } from "bun";

await $`bun input.js | bun prompt.js`;
```

```js#prompt.js
const { select } = require("@inquirer/prompts");

async function run() {
  const foobar = await select({
    message: "Foo or Bar",
    choices: [
      { name: "Foo", value: "foo" },
      { name: "Bar", value: "bar" },
    ],
  });
  console.error("Choice:", foobar);
}

run();
```

```js#input.js
// Simulate pressing the down arrow key
const writer = Bun.stdout.writer();
await Bun.sleep(100);
writer.write("\\x1b[B");

// Simulate pressing the enter key
await Bun.sleep(100);
writer.write("\\x0D");
writer.flush();
```

{% /codetabs %}

Thanks to [@zackradisic](https://github.com/zackradisic) for fixing these issue.

## Fixed: `bun build --target bun` used wrong encoding

Bun transpiles files to latin1 because the file size is reduced when being stored as utf-16. There was a bug where `bun build --target bun` would encode as utf-8 instead, which caused issues with non-latin1 characters. This has been fixed.

Given the following file, previously it would have been encoded as-is in utf-8.

```js
console.log({ 我: "a" });
```

Now, it is encoded properly in latin1.

```js
// @bun
console.log({ "\u{6211}": "a" });
```

Thanks to [@pfgithub](https://github.com/pfgithub) for fixing this issue.

## Bundows (Bun v1.1) is April 1st

[Bun v1.1](https://www.youtube.com/watch?v=yXTFOeGly9o) will ship on April 1st.

## Thank you to 13 contributors!

- [@buhrmi](https://github.com/buhrmi)
- [@cirospaciari](https://github.com/cirospaciari)
- [@davlgd](https://github.com/davlgd)
- [@dylan-conway](https://github.com/dylan-conway)
- [@eduardvercaemer](https://github.com/eduardvercaemer)
- [@Jarred-Sumner](https://github.com/Jarred-Sumner)
- [@kucukkanat](https://github.com/kucukkanat)
- [@kunokareal](https://github.com/kunokareal)
- [@nshen](https://github.com/nshen)
- [@paperclover](https://github.com/paperclover)
- [@pfgithub](https://github.com/pfgithub)
- [@sequencerr](https://github.com/sequencerr)
- [@zackradisic](https://github.com/zackradisic)
