Bun v1.2.22 Bun v1.2.22 introduces several key improvements, including async stack traces that now show the full asynchronous execution path for easier debugging, and a new fast path that makes `postMessage` and `structuredClone` up to 240x faster for simple objects containing only primitive values. The update also adds `Bun.YAML.stringify` for converting JavaScript objects to YAML, fixes support for interactive TTYs after stdin closes, and improves the MySQL adapter for Bun.SQL by adding `affectedRows` and `lastInsertRowid` properties. To install Bun curl -fsSL https://bun.sh/install | bash npm install -g bun powershell -c "irm bun.sh/install.ps1|iex" scoop install 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 Async Stack Traces async-stack-traces Bun's stack traces now include asynchronous call frames, making it significantly easier to debug code using async / await . Previously, these frames were omitted, leading to incomplete stack traces. Now, you'll see the full asynchronous execution path leading to an error. async function foo { return await bar ; } async function bar { return await baz ; } async function baz { await 1; // ensure it's a real async function throw new Error "oops" ; } try { await foo ; } catch e { console.log e ; } This now outputs: ❯ bun async.js 6 | return await baz ; 7 | } 8 | 9 | async function baz { 10 | await 1; // ensure it's a real async function 11 | throw new Error "oops" ; ^ error: oops at baz async.js:11:13 at async bar async.js:6:16 at async foo async.js:2:16 Previously, it would output: ❯ bun-1.2.21 async.js 6 | return await baz ; 7 | } 8 | 9 | async function baz { 10 | await 1; // ensure it's a real async function 11 | throw new Error "oops" ; ^ error: oops at baz async.js:11:9 Additionally, a bug that could cause stack traces printed to the console to be missing frames after accessing error.stack has been fixed. And a bug with the error stack for Error subclases has been fixed. In the next version of Bun & Safari — Bun @bunjavascript Error subclasses show where the error was thrown as the 1st frame instead of the subclass' constructor, thanks to @ sosukesuzuki pic.twitter.com/NC8Ex9DC3K September 1, 2025 Huge thanks to @sosukesuzuki for implementing this in JavaScriptCore 240x faster 240x-faster-postmessage-and-structuredclone-for-simple-objects postMessage and structuredClone for simple objects postMessage and structuredClone for simple objectsA new fast path has been added for postMessage and structuredClone when dealing with "simple" objects. This optimization applies to plain JavaScript objects that contain only primitive values like strings, numbers, booleans, null , and undefined . In the next version of Bun — Jarred Sumner @jarredsumner postMessage object gets up to 200x faster for objects with strings or primitive values. pic.twitter.com/Z4Nrj4HtJL August 31, 2025 Bun.YAML.stringify Bun.YAML.stringify In the next version of Bun — Bun @bunjavascript Bun.YAML.stringify converts JavaScript objects into YAML pic.twitter.com/ioaSb07EPX August 27, 2025 Support for interactive TTYs after support-for-interactive-ttys-after-stdin-closes stdin closes stdin closesA common pattern for TUI Terminal User Interface applications is to first process data piped from stdin , and then open /dev/tty to start an interactive session. This pattern was previously broken in Bun, causing an ESPIPE error when reading from the TTY stream. This has been fixed by correctly handling file streams for character devices. Additionally, tty.ReadStream now supports .ref and .unref for parity with Node.js, allowing for better control over the event loop in TUI applications. This resolves a long-standing bug affecting many interactive CLI tools. js import { createReadStream } from "fs"; import { stdin, stdout } from "process"; // 1. Process any data piped from stdin for await const chunk of stdin { stdout.write Piped data: ${chunk} ; } // 2. After stdin closes, open /dev/tty for interactive input stdout.write "stdin closed. Now accepting interactive input type 'exit' to quit :\n" ; const tty = createReadStream "/dev/tty" ; for await const chunk of tty { const line = chunk.toString .trim ; stdout.write You typed: "${line}"\n ; if line === "exit" { tty.destroy ; } } To run: echo "Initial data" | bun script.js Bun.SQL improvements bun-sql-improvements MySQL Adapter mysql-adapter In Bun v1.2.21, we introduced MySQL & SQLite adapters for Bun.SQL . This release includes several improvements to the MySQL adapter. affectedRows and lastInsertRowid affectedRows and lastInsertRowid properties are now returned by the MySQL driver. affectedRows contains the number of rows changed by the query, and lastInsertRowid contains the ID of the last inserted row. This brings the MySQL driver's API closer to Bun.SQL . js import { sql } from "bun"; // For INSERT queries const insertResult = await sql INSERT INTO users name VALUES 'John Doe' ; ; console.log insertResult.lastInsertRowid ; // e.g., 1 console.log insertResult.affectedRows ; // 1 // For UPDATE queries const updateResult = await sql UPDATE users SET name = 'Jane Doe' WHERE id = 1; ; console.log updateResult.affectedRows ; // 1 Better column type handling Thanks to community feedback, we've made the following improvements to MySQL driver's column type handling: | MySQL Type | JavaScript Type | Notes | |---|---|---| | INT, TINYINT, MEDIUMINT | number | Within safe integer range | | BIT 1 | boolean | Previously: TINYINT columns were incorrectly parsed as booleans instead of numbers. BIT 1 columns were incorrectly parsed as numbers instead of booleans. BIT N columns where N 1 were incorrectly parsed as Buffer s instead of numbers, but only when the binary protocol was used. TLS Support Bun.SQL now supports connecting to MySQL databases over a TLS/SSL connection. This is done by passing a tls option to the Bun.SQL constructor, matching the behavior of the PostgreSQL adapter and other Bun APIs. mysql native password authentication Bun.SQL now correctly handles mysql native password authentication and authentication switching, improving compatibility with a wider range of MySQL servers. PostgreSQL improvements postgresql-improvements - Fixed: A bug in Bun.SQL 's Postgres driver where an error in a pipelined query could cause the connection to disconnect. - Fixed: In certain cases, Bun.SQL could resolve a PostgreSQL query's Promise before the server reported being ready. - Fixed: Bun.SQL now correctly decodes TIME and TIMETZ columns from PostgreSQL when using the binary protocol. Bundler & minifier bundler-minifier In the next version of Bun — Bun @bunjavascript Bun's JavaScript transpiler & minifier gets slightly smarter pic.twitter.com/W84u1C9Q7a September 4, 2025 Minifier optimizes minifier-optimizes-new-expressions-for-smaller-bundles new expressions for smaller bundles new expressions for smaller bundlesBun's JavaScript minifier now implements several new optimizations for built-in constructors, resulting in smaller bundle sizes. When constructing built-in objects like Object , Array , or Error , the new keyword is often optional and has no effect on the runtime behavior. Bun now automatically removes the new keyword or replaces the entire expression with a more compact literal form, such as converting new Object to {} . This optimization applies to new Object , new Array , new Error and its subtypes , and new Function . js -const obj=new Object ; +const obj={}; -const arr=new Array 1, 2, 3 ; +const arr= 1,2,3 ; -const err=new Error "Something went wrong" ; +const err=Error "Something went wrong" ; Thanks to @dylan-conway for the contribution typeof undefined checks are now minified typeof undefined checks are now minifiedBun's minifier now optimizes typeof checks for "undefined" . This common optimization, also used by tools like esbuild, reduces bundle size by replacing string comparisons with shorter character comparisons. This change also improves dead code elimination for code guarded by these checks. // Input console.log typeof x === "undefined" ; console.log typeof x == "undefined" ; // Minified output console.log typeof x "u" ; console.log typeof x < "u" ; Thanks to @Jarred-Sumner and @dylan-conway for this change onEnd hook for bundler plugins onEnd hook for bundler plugins Bun.build now supports the onEnd hook in plugins, aligning its plugin API closer to esbuild. This hook is triggered after a build is complete—whether it succeeds or fails—and provides access to the BuildOutput object. This is useful for post-processing, cleanup, or sending notifications. await Bun.build { entrypoints: "./index.ts" , outdir: "./out", plugins: { name: "onEnd example", setup build { build.onEnd result = { if result.success { console.log ✅ Build succeeded with ${result.outputs.length} outputs , ; } else { console.error ❌ Build failed with ${result.logs.length} errors ; } } ; }, }, , } ; Thanks to @alii for the contribution jsxSideEffects option jsxSideEffects optionBy default, Bun's bundler treats JSX as "pure", meaning it can be removed if its return value is unused. This process, known as dead code elimination, can cause problems when a component has side effects that need to be preserved. A new option, jsxSideEffects , has been introduced to prevent this. When set to true , Bun will no longer mark JSX as pure, ensuring that components with side effects are always included in the final bundle. You can enable this feature in your tsconfig.json or by using a command-line flag. // tsconfig.json { "compilerOptions": { "jsxSideEffects": true } } This ensures that code with side effects, like the example below, behaves as expected. js // component.jsx let counter = 0; function MyComponent { counter++; // This side effect will now be preserved return