---
title: Bun v1.2.21
description: "Fixes 69 issues (addressing 204 👍). Bun.SQL now supports MySQL and SQLite, alongside PostgreSQL. Native YAML support. 500x faster postMessage(string). Bun.build() compile API, with cross-platform targets. Reduced idle CPU usage. Bun.stripANSI for SIMD-accelerated ANSI escape removal. bunx --package flag support. customizable User-Agent headers. Windows executable metadata embedding. and extensive Node.js compatibility improvements"
date: "2025-08-25T22:54:53.268Z"
author: jarred
---

This release fixes 69 issues (addressing 204 👍).

#### To install Bun

{% codetabs %}

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

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

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

```sh#scoop
$ scoop install 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
```

## `Bun.SQL` - unified SQL client

You can now use `Bun.SQL` to connect to MySQL/MariaDB, SQLite, and PostgreSQL. The same database library just works for the three most popular SQL databases, with zero dependencies.

### MySQL & MariaDB in `Bun.SQL`

Bun's MySQL/MariaDB driver is written in Zig.

{% image src="/images/bun-mysql-fast.png" alt="Bun.SQL - MySQL/MariaDB" /%}

To get started, you can pass either an options object or a URL string to the `SQL` constructor.

```ts
import { SQL } from "bun";

// Connect to a MySQL or MariaDB database
const sql = new SQL({
  adapter: "mysql",
  hostname: "127.0.0.1",
  username: "user",
  password: "password",
  database: "buns_burgers",
});

// Run a query
const users = await sql`SELECT * FROM users;`.all();
console.log(users);

// or via url
const mysql = new SQL("mysql://user:password@127.0.0.1:3306/buns_burgers");

// Run a query
const users = await mysql`SELECT * FROM users;`;
console.log(users);
```

Thanks to @cirospaciari for the contribution

<!-- https://github.com/oven-sh/bun/commit/ecbf103bf5356963bf3ed48f51e3cc59a03fdbe4 -->

### SQLite in `Bun.SQL`

`Bun.SQL` now also has built-in SQLite support. This brings the same simple and performant tagged template literal API that was previously only available for PostgreSQL to SQLite users.

You can create an in-memory database by passing `":memory:"` or a file-based database by providing a path like `sqlite://path/to/db.sqlite`.

```js
import { SQL } from "bun";

// Create an in-memory SQLite database
const db = new SQL(":memory:");

// Create a table
await db`CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)`;

// Insert multiple users
const names = ["Alice", "Bob"];
await db`INSERT INTO users (name) VALUES ${SQL.values(
  names.map((name) => [name]),
)}`;

// Query the users
const users = await db`SELECT * FROM users ORDER BY name ASC`;
console.log(users);
// => [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]
```

Thanks to @alii for the contribution!

## Native YAML support

Bun now has a built-in YAML parser. You can import `.yaml` and `.yml` files directly, or parse YAML strings at runtime using `Bun.YAML.parse`. This works just like Bun's built-in support for JSON and TOML.

{% raw %}

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">In the next version of Bun<br><br>Native YAML support comes to JavaScript<br><br>Import, bundle, require and parse YAML in JS as easily as JSON <a href="https://t.co/5TYRLDoZgM">pic.twitter.com/5TYRLDoZgM</a></p>&mdash; Bun (@bunjavascript) <a href="https://twitter.com/bunjavascript/status/1959232097563869470?ref_src=twsrc%5Etfw">August 23, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

{% /raw %}

To import a YAML file, you can `import` it as you would a JavaScript module. Bun will parse the file and export its contents as the default export.

```js#package.yaml
name: my-package
version: 1.1.1
```

```js#index.js
import pkg from "./package.yaml";

console.log(pkg.name); // "my-package"
console.log(pkg.version); // "1.1.1"
```

To parse a YAML string, use the `Bun.YAML.parse` function.

```js
import { YAML } from "bun";

const text = `
- item1
- item2
`;

const items = YAML.parse(text);
console.log(items); // [ "item1", "item2" ]
```

Thanks to @dylan-conway for the contribution!

## 500x faster `postMessage(string)`

Sending strings between workers using `postMessage` and cloning strings with `structuredClone` is now significantly faster.

[Learn more](https://bun.com/blog/how-we-made-postMessage-string-500x-faster)

## `Bun.secrets` - native secrets manager for CLI tools

`Bun.secrets` securely stores and retrieves credentials using the operating system's native credential storage. This helps avoid storing sensitive data in plaintext files which is especially useful for CLI tools and local development.

It uses Keychain Services on macOS, `libsecret` (GNOME Keyring, KWallet) on Linux, and the Windows Credential Manager. All operations (`get`, `set`, and `delete`) are asynchronous and run in Bun's thread pool.

```js
import { secrets } from "bun";

// Store a GitHub token securely
await secrets.set({
  service: "my-cli-tool",
  name: "github-token",
  value: "ghp_xxxxxxxxxxxxxxxxxxxx",
});

// Retrieve it when needed
const token = await secrets.get({
  service: "my-cli-tool",
  name: "github-token",
});

// Or delete it later
await secrets.delete({
  service: "my-cli-tool",
  name: "github-token",
});
```

<!-- https://github.com/oven-sh/bun/commit/707fc4c3a2debeac9fe0c38cd318c9d890bcb615 -->

## Security Scanner API for `bun install`

Bun's package manager can now scan packages for security vulnerabilities before installation, helping protect your applications from supply chain attacks and known vulnerabilities.

To enable this feature, install a security scanner package from npm and configure it in your `bunfig.toml`. When a scanner is configured, `bun install` will invoke it, and the installation will be cancelled if vulnerabilities with `fatal` severity are found.

```toml
# bunfig.toml

[install.security]
# First, run `bun add -d @my-company/bun-security-scanner`
scanner = "@my-company/bun-security-scanner"
```

You can learn more about this API [in our docs](https://bun.com/docs/install/security-scanner-api). For a quickstart on building a security scanner, see our [template repository](https://github.com/oven-sh/security-scanner-template).

Thanks to @alii for the contribution!

## `bun audit` gets new filtering options

The `bun audit` command now supports new flags for filtering vulnerabilities, giving you more control over your security audits.

- `--audit-level=<level>`: Only report vulnerabilities with a severity of `<level>` or higher. The supported levels are `low`, `moderate`, `high`, and `critical`.
- `--prod`: Restricts the audit to only production dependencies, ignoring `devDependencies`.
- `--ignore=<CVE>`: Allows you to ignore specific vulnerabilities by their CVE ID. This flag can be used multiple times.

These flags make it easier to integrate `bun audit` into CI/CD pipelines by allowing you to focus on the most critical security issues relevant to your application.

```sh
# Only report high and critical vulnerabilities
bun audit --audit-level=high

# Audit only production dependencies
bun audit --prod

# Ignore a specific vulnerability
bun audit --ignore CVE-2023-12345

# Ignore multiple vulnerabilities
bun audit --ignore CVE-2023-12345 --ignore CVE-2023-67890
```

Thanks to @RiskyMH for the contribution

## `bun install --lockfile-only` is much faster

The `bun install --lockfile-only` command has been optimized to avoid downloading package tarballs from the npm registry. It now only fetches package manifests, which contain all the necessary information to generate or update `bun.lock`.

This change significantly reduces network bandwidth usage and improves performance, especially in CI environments or for projects with many dependencies. For non-npm dependencies, such as direct tarball URLs or Git repositories, the tarballs are still downloaded to ensure the lockfile's accuracy.

## `bun update --interactive` supports scrolling

The interactive mode for `bun update` (`bun update -i` or `bun update --interactive`) now supports scrolling. When the list of updatable dependencies exceeds the height of your terminal, you can use the up and down arrow keys to navigate the full list.

Additionally, the table display is now responsive to your terminal's width. Long package names will be truncated to ensure the layout remains clean and readable on smaller screens.

Thanks to @RiskyMH for the contribution

<!-- https://github.com/oven-sh/bun/commit/659f9365ea837211821f7bfac73c9ec85c946e53 -->

## Reduced idle CPU usage

Previously, `Bun.serve` would wake up every second to update a cached `Date` header for HTTP responses. This caused Bun's process to use a small amount of CPU and trigger context switches, even when the server was completely idle or not even used at all.

{% image src="/images/idle-1.2.21.png" caption="setTimeout benchmark" /%}

Now, this timer is only active when there are in-flight requests. When a server is idle, Bun's process will now truly sleep, consuming virtually no CPU resources.

## `Bun.build()` now supports compiling executables

You can now create standalone executables with the `Bun.build()` JavaScript API. This functionality, previously only available via the `bun build --compile` CLI flag, is now accessible programmatically. Bundler plugins are also now fully supported when compiling an executable.

The new `compile` option in `Bun.build` accepts `true` to build for the current platform, a target string like `'bun-linux-x64'`, or a configuration object for more advanced options.

```ts
// Cross-compile an executable for Linux x64 with musl
await Bun.build({
  entrypoints: ["./cli.ts"],
  // target can be a shorthand string where it uses entrypoint name as executable name
  compile: "bun-linux-x64-musl",
});

// Or use an object for more configuration, like setting a custom filename and Windows icon
await Bun.build({
  entrypoints: ["./cli.ts"],
  compile: {
    target: "bun-windows-x64",
    outfile: "./my-app-windows",
    windows: {
      // set the icon for the .exe
      icon: "./icon.ico",
    },
  },
});
```

Thanks to @RiskyMH for the contribution

<!-- https://github.com/oven-sh/bun/commit/d354714791e7f43e5588fbb6cc728b2700075856 -->

### Embed runtime flags into standalone executables with `--compile-exec-argv`

The `bun build --compile` command now supports a new `--compile-exec-argv` flag that lets you embed runtime arguments directly into a standalone executable.

When the compiled binary is executed, these arguments are processed by the Bun runtime as if they were passed on the command line. This allows you to create specialized builds with different runtime characteristics, such as enabling the inspector, setting a default user-agent, or optimizing for memory usage. The embedded arguments are also available for inspection via `process.execArgv`.

```ts
// index.ts
console.log(`Bun was launched with: ${process.execArgv.join(" ")}`);

// This --user-agent flag is actually processed by Bun's runtime.
// All fetch requests will use this user-agent.
const res = await fetch("https://api.bunjstest.com/agent");
console.log(`User-Agent header sent: ${await res.text()}`);
```

You can build this file with embedded arguments.

```sh
$ bun build ./index.ts --compile --outfile=my-app \
  --compile-exec-argv="--smol --user-agent=MyApp/1.0"

$ ./my-app
Bun was launched with: --smol --user-agent=MyApp/1.0
User-Agent header sent: MyApp/1.0
```

<!-- https://github.com/oven-sh/bun/commit/151cc59d538850f87894964a651214503c934c5f -->

### Set metadata for Windows executables

You can now embed metadata into standalone executables for Windows using `bun build --compile`. This allows you to set the application's title, publisher, version, description, and copyright, which will be visible in the file properties in Windows Explorer.

This is supported via a new set of CLI flags:

- `--windows-title`
- `--windows-publisher`
- `--windows-version`
- `--windows-description`
- `--windows-copyright`

These options are also available in the `Bun.build()` API via the `compile.windows` object.

```js
await Bun.build({
  entrypoints: ["./app.js"],
  outfile: "./app.exe",
  compile: {
    windows: {
      title: "My Cool App",
      publisher: "My Company",
      version: "1.2.3.4",
      description: "This is a really cool application.",
      copyright: "© 2024 My Company",
    },
  },
});
```

Thanks to @RiskyMH for the contribution

## `Bun.stripANSI()` - SIMD-accelerated ANSI escape removal

`Bun.stripANSI()` lets you strip ANSI escape codes from a string. It serves as a high-performance, built-in alternative to the `strip-ansi` package from npm, running between 6x and 57x faster.

```js
const coloredText = "\u001b[31mHello\u001b[0m \u001b[32mWorld\u001b[0m";
const plainText = Bun.stripANSI(coloredText);
console.log(plainText); // => "Hello World"

// Works with various ANSI codes
const formatted = "\u001b[1m\u001b[4mBold and underlined\u001b[0m";
console.log(Bun.stripANSI(formatted)); // => "Bold and underlined"
```

Thanks to @taylordotfish for the contribution!

## Codesigned `bun.exe` for Windows

`bun.exe` for Windows is now code-signed, which resolves a security warning that could appear when running it for the first time.

Thanks to @connerlphillippi for the contribution!

## `bunx` now supports `--package`

You can now use the `--package` (or `-p`) flag with `bunx` to run a binary from a package where the binary's name differs from the package's name. This is useful for packages that ship multiple binaries or for scoped packages. This brings `bunx`'s functionality in line with `npx` and `yarn dlx`.

For example, the `renovate` package provides a `renovate-config-validator` binary. You can now run it directly:

```sh
# Run the `renovate-config-validator` binary from the `renovate` package
bunx --package renovate renovate-config-validator
```

Similarly, to use the `ng` binary from the `@angular/cli` package:

```sh
# Run the `ng` binary from the `@angular/cli` package
bunx -p @angular/cli ng new my-app
```

Thanks to @RiskyMH for the contribution

<!-- https://github.com/oven-sh/bun/commit/3cf6da9c9b7f030f0d7dbf5f92fd7c64be600c0e -->

## `package.json` `sideEffects` now supports glob patterns

Bun's bundler now supports using glob patterns in the `sideEffects` field of `package.json`. This allows for more precise tree-shaking and can lead to smaller bundle sizes, especially when using component libraries that rely on this feature.

Previously, using a glob pattern would cause Bun to de-optimize the entire package. Now, Bun correctly identifies which files have side effects based on the provided patterns.

Supported patterns include `*`, `?`, `**`, `[]`, and `{}`.

```json
// package.json
{
  "name": "my-package",
  "sideEffects": ["**/*.css", "./src/setup.js", "./src/components/*.js"]
}
```

In the example above, Bun will correctly preserve all CSS files, `src/setup.js`, and any JavaScript files directly inside `src/components/`, while tree-shaking other modules if they are not used.

Thanks to @RiskyMH for the contribution

## Customize `User-Agent` with the `--user-agent` flag

A new `--user-agent` flag has been added to the Bun CLI. This allows you to override the default `User-Agent` header for all HTTP requests made using `fetch()` within your application. This is useful for identifying your application to external services or for APIs that require a specific `User-Agent`.

```js#agent.js
const response = await fetch("https://httpbin.org/user-agent");
const data = await response.json();
console.log(data["user-agent"]);
```

```sh
# Run with a custom user agent
$ bun --user-agent "MyCustomApp/1.0" agent.js
MyCustomApp/1.0

# Without the flag, it uses the default
$ bun agent.js
Bun/1.2.18
```

<!-- https://github.com/oven-sh/bun/commit/599947de2889d02de0f8a08c3b56c6bb3b58cc6e -->

## Node.js compatibility improvements

- Fixed: `TypeError` when using `ws` that could occur when a WebSocket upgrade is aborted or fails (server-side)
- Fixed: `process.exit()` in a Worker now correctly notifies N-API callers that the VM is terminating, improving Node.js compatibility.
- Fixed: assertion failure during process exit when using NAPI addons, such as `node-sqlite3`, that trigger garbage collection within their finalizers.
- Fixed: assertion failure that could occur in native addons when `napi_is_exception_pending` is called from an object finalizer.
- Fixed: assertion failure when reading a file with an odd number of bytes using `utf16le` or `ucs2` encoding.
- Fixed: assertion failure when terminating a Worker that called `process.exit`.
- Fixed: assertion failure when using N-API native addons like `lmdb` that attempt to remove a cleanup hook that has already been removed or was never added. Bun's behavior is now aligned with Node.js, which silently ignores this operation.
- Fixed: bug in `child_process` that occurred when stdio streams were destroyed too quickly. Bun now `stream.Readable` and `stream.Writable` instances just like Node.js.
- Fixed: bug when `Error.prepareStackTrace` was called with a `null`, `undefined`, or other non-array value as the second argument.
- Fixed: bug where exceptions thrown from N-API modules were propagated to JavaScript too quickly, which could lead to a crash.
- Fixed: bug where `readline.createInterface()` from `node:readline/promises` did not implement `[Symbol.dispose]`, preventing its use with `using` declarations.
- Fixed: bugs in `structuredClone` where certain non-transferable objects were handled incorrectly.
- Fixed: deadlock in `net.BlockList` that could occur when the same instance was accessed from multiple threads simultaneously.
- Fixed: rare race condition in inter-process communication (IPC) that could lead to a crash when using `node:cluster`.
- Fixed: regression in `node:crypto` where functions like `crypto.sign()` would fail when using lowercase algorithm names, such as `'rsa-sha256'`. This improves compatibility with Node.js and fixes libraries like `mailauth`.

## Bundler & parser bugfixes

- Fixed: assertion failure in the JavaScript lexer when parsing an invalid template string in a JSX element, such as `<div a=\`\`/>`.
- Fixed: assertion failure in the CSS parser when bundling stylesheets with large floating-point values, such as those generated by TailwindCSS's `rounded-full` utility.
- Fixed a bug where `String contains an invalid character` would be thrown when rendering multiple frontend errors in Bun's frontend development server.

## Bun.SQL bugfixes

- Fixed: Bun.SQL error classes are all now exported, accessible under `Bun.SQL.PostgresError`, `Bun.SQL.SQLiteError` and `Bun.SQL.MySQLError`. This allows for type-safe error handling like `error instanceof Bun.SQL.PostgresError`. You can also use the superclass they all extend, `Bun.SQL.SQLError`.
- Fixed: Unix domain sockets would fail to connect when using PostgreSQL in certain configurations, often resulting in a `PostgresError: Connection closed`.
- `sql(["a", "b", "c"])` now supports string arrays in `WHERE IN` clauses. Thanks to @zenazn for the contribution.

## bun install bugfixes

- Fixed: A UI flickering issue in `bun update --interactive` has been resolved, providing a smoother experience.
- Fixed: `yarn.lock` migrations for packages with long version strings, such as those that include git commit SHAs
- Fixed: assertion failure in Bun's logger that could occur when processing source locations.
- Fixed: assertion failure in `bun install` when parsing a malformed or oversized integrity hash in a `bun.lockb` file
- Fixed: assertion failure that could occur when parsing a `package.json` with top-level catalog configurations.
- Fixed: bug where `bun init` would list `CLAUDE.md` twice in the summary of created files.

## Runtime bugfixes

- Fixed: typo in the `bun upgrade` error message, which caused an extra closing parenthesis to be printed on verification failure, has been corrected.
- Fixed: `Bun.hash.xxHash64` to correctly handle `BigInt` seeds larger than 32-bits
- Fixed: `Bun.serve()` would incorrectly reject a `tls` array with a single configuration object
- Fixed: bug impacting Windows when using pipelines in `bun shell` (`$`)
- Fixed: bug that could occur when calling `server.stop()` on a `Bun.serve` instance while requests were still being processed
- Fixed: bug where `Bun.serve` would add a `Date` header to an HTTP response even if one was already present, resulting in duplicate `Date` headers
- Fixed: crash in `HTMLRewriter` when an element handler throws an exception. This change also resolves a memory leak when parsing invalid CSS selectors and improves error messages for them.
- Fixed: namespace import objects (`import * as ns from '...'`) incorrectly inherited from `Object.prototype`. Please let us know if this breaks anything
- Improved internal exception handling in `bun:sqlite`
- `expect(...).toBeCloseTo(...)` is now correctly counted in the total number of expect calls reported by `bun test`.

### Thanks to 23 contributors!

- [@alii](https://github.com/alii)
- [@cirospaciari](https://github.com/cirospaciari)
- [@connerlphillippi](https://github.com/connerlphillippi)
- [@creationix](https://github.com/creationix)
- [@dylan-conway](https://github.com/dylan-conway)
- [@heimskr](https://github.com/heimskr)
- [@imranbarbhuiya](https://github.com/imranbarbhuiya)
- [@jarred-sumner](https://github.com/jarred-sumner)
- [@lifefloating](https://github.com/lifefloating)
- [@lydiahallie](https://github.com/lydiahallie)
- [@markovejnovic](https://github.com/markovejnovic)
- [@nektro](https://github.com/nektro)
- [@pfgithub](https://github.com/pfgithub)
- [@riskymh](https://github.com/riskymh)
- [@rmncldyo](https://github.com/rmncldyo)
- [@robobun](https://github.com/robobun)
- [@sanderjo](https://github.com/sanderjo)
- [@someone19204](https://github.com/someone19204)
- [@sosukesuzuki](https://github.com/sosukesuzuki)
- [@taylordotfish](https://github.com/taylordotfish)
- [@zackradisic](https://github.com/zackradisic)
- [@zenazn](https://github.com/zenazn)
