{"slug": "bun-v1-2-22", "title": "Bun v1.2.22", "summary": "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.", "body_md": "#### To install Bun\n\n```\ncurl -fsSL https://bun.sh/install | bash\nnpm install -g bun\npowershell -c \"irm bun.sh/install.ps1|iex\"\nscoop install bun\nbrew tap oven-sh/bun\nbrew install bun\ndocker pull oven/bun\ndocker run --rm --init --ulimit memlock=-1:-1 oven/bun\n```\n\n#### To upgrade Bun\n\n```\nbun upgrade\n```\n\n[Async Stack Traces](#async-stack-traces)\n\nBun's stack traces now include asynchronous call frames, making it significantly easier to debug code using `async`\n\n/`await`\n\n. Previously, these frames were omitted, leading to incomplete stack traces. Now, you'll see the full asynchronous execution path leading to an error.\n\n```\nasync function foo() {\n  return await bar();\n}\n\nasync function bar() {\n  return await baz();\n}\n\nasync function baz() {\n  await 1; // ensure it's a real async function\n  throw new Error(\"oops\");\n}\n\ntry {\n  await foo();\n} catch (e) {\n  console.log(e);\n}\n```\n\nThis now outputs:\n\n```\n❯ bun async.js\n 6 |   return await baz();\n 7 | }\n 8 |\n 9 | async function baz() {\n10 |   await 1; // ensure it's a real async function\n11 |   throw new Error(\"oops\");\n                 ^\nerror: oops\n      at baz (async.js:11:13)\n      at async bar (async.js:6:16)\n      at async foo (async.js:2:16)\n```\n\nPreviously, it would output:\n\n```\n❯ bun-1.2.21 async.js\n 6 |   return await baz();\n 7 | }\n 8 |\n 9 | async function baz() {\n10 |   await 1; // ensure it's a real async function\n11 |   throw new Error(\"oops\");\n             ^\nerror: oops\n      at baz (async.js:11:9)\n```\n\nAdditionally, a bug that could cause stack traces printed to the console to be missing frames after accessing `error.stack`\n\nhas been fixed.\n\nAnd a bug with the error stack for Error subclases has been fixed.\n\nIn the next version of Bun & Safari\n\n— Bun (@bunjavascript)\n\nError 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]\n\nHuge thanks to @sosukesuzuki for implementing this in JavaScriptCore!\n\n[240x faster ](#240x-faster-postmessage-and-structuredclone-for-simple-objects)`postMessage`\n\nand `structuredClone`\n\nfor simple objects\n\n`postMessage`\n\nand `structuredClone`\n\nfor simple objectsA new fast path has been added for `postMessage`\n\nand `structuredClone`\n\nwhen dealing with \"simple\" objects. This optimization applies to plain JavaScript objects that contain only primitive values like strings, numbers, booleans, `null`\n\n, and `undefined`\n\n.\n\nIn the next version of Bun\n\n— Jarred Sumner (@jarredsumner)\n\npostMessage(object) gets up to 200x faster for objects with strings or primitive values.[pic.twitter.com/Z4Nrj4HtJL][August 31, 2025]\n\n`Bun.YAML.stringify`\n\n`Bun.YAML.stringify`\n\nIn the next version of Bun\n\n— Bun (@bunjavascript)\n\nBun.YAML.stringify converts JavaScript objects into YAML[pic.twitter.com/ioaSb07EPX][August 27, 2025]\n\n[Support for interactive TTYs after ](#support-for-interactive-ttys-after-stdin-closes)`stdin`\n\ncloses\n\n`stdin`\n\nclosesA common pattern for TUI (Terminal User Interface) applications is to first process data piped from `stdin`\n\n, and then open `/dev/tty`\n\nto start an interactive session. This pattern was previously broken in Bun, causing an `ESPIPE`\n\nerror when reading from the TTY stream.\n\nThis has been fixed by correctly handling file streams for character devices. Additionally, `tty.ReadStream`\n\nnow supports `.ref()`\n\nand `.unref()`\n\nfor 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.\n\n``` js\nimport { createReadStream } from \"fs\";\nimport { stdin, stdout } from \"process\";\n\n// 1. Process any data piped from stdin\nfor await (const chunk of stdin) {\n  stdout.write(`Piped data: ${chunk}`);\n}\n\n// 2. After stdin closes, open /dev/tty for interactive input\nstdout.write(\n  \"stdin closed. Now accepting interactive input (type 'exit' to quit):\\n\"\n);\nconst tty = createReadStream(\"/dev/tty\");\n\nfor await (const chunk of tty) {\n  const line = chunk.toString().trim();\n  stdout.write(`You typed: \"${line}\"\\n`);\n  if (line === \"exit\") {\n    tty.destroy();\n  }\n}\n```\n\nTo run:\n\n```\necho \"Initial data\" | bun script.js\n```\n\n[Bun.SQL improvements](#bun-sql-improvements)\n\n[MySQL Adapter](#mysql-adapter)\n\nIn Bun v1.2.21, we introduced MySQL & SQLite adapters for `Bun.SQL`\n\n. This release includes several improvements to the MySQL adapter.\n\n`affectedRows`\n\nand `lastInsertRowid`\n\n`affectedRows`\n\nand `lastInsertRowid`\n\nproperties are now returned by the MySQL driver. `affectedRows`\n\ncontains the number of rows changed by the query, and `lastInsertRowid`\n\ncontains the ID of the last inserted row. This brings the MySQL driver's API closer to `Bun.SQL`\n\n.\n\n``` js\nimport { sql } from \"bun\";\n\n// For INSERT queries\nconst insertResult = await sql`INSERT INTO users (name) VALUES ('John Doe');`;\nconsole.log(insertResult.lastInsertRowid); // e.g., 1\nconsole.log(insertResult.affectedRows); // 1\n\n// For UPDATE queries\nconst updateResult =\n  await sql`UPDATE users SET name = 'Jane Doe' WHERE id = 1;`;\nconsole.log(updateResult.affectedRows); // 1\n```\n\n#### Better column type handling\n\nThanks to community feedback, we've made the following improvements to MySQL driver's column type handling:\n\n| MySQL Type | JavaScript Type | Notes |\n|---|---|---|\n| INT, TINYINT, MEDIUMINT | number | Within safe integer range |\n| BIT(1) | boolean |\n\nPreviously:\n\n`TINYINT`\n\ncolumns were incorrectly parsed as booleans instead of numbers.`BIT(1)`\n\ncolumns were incorrectly parsed as numbers instead of booleans.`BIT(N)`\n\ncolumns (where N > 1) were incorrectly parsed as`Buffer`\n\ns instead of numbers, but only when the binary protocol was used.\n\n#### TLS Support\n\n`Bun.SQL`\n\nnow supports connecting to MySQL databases over a TLS/SSL connection. This is done by passing a `tls`\n\noption to the `Bun.SQL`\n\nconstructor, matching the behavior of the PostgreSQL adapter and other Bun APIs.\n\n`mysql_native_password`\n\nauthentication\n\n`Bun.SQL`\n\nnow correctly handles `mysql_native_password`\n\nauthentication and authentication switching, improving compatibility with a wider range of MySQL servers.\n\n[PostgreSQL improvements](#postgresql-improvements)\n\n- Fixed: A bug in\n`Bun.SQL`\n\n'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.\n- Fixed: Bun.SQL now correctly decodes\n`TIME`\n\nand`TIMETZ`\n\ncolumns from PostgreSQL when using the binary protocol.\n\n[Bundler & minifier](#bundler-minifier)\n\nIn the next version of Bun\n\n— Bun (@bunjavascript)\n\nBun's JavaScript transpiler & minifier gets slightly smarter[pic.twitter.com/W84u1C9Q7a][September 4, 2025]\n\n[Minifier optimizes ](#minifier-optimizes-new-expressions-for-smaller-bundles)`new`\n\nexpressions for smaller bundles\n\n`new`\n\nexpressions for smaller bundlesBun's JavaScript minifier now implements several new optimizations for built-in constructors, resulting in smaller bundle sizes.\n\nWhen constructing built-in objects like `Object`\n\n, `Array`\n\n, or `Error`\n\n, the `new`\n\nkeyword is often optional and has no effect on the runtime behavior. Bun now automatically removes the `new`\n\nkeyword or replaces the entire expression with a more compact literal form, such as converting `new Object()`\n\nto `{}`\n\n.\n\nThis optimization applies to `new Object()`\n\n, `new Array()`\n\n, `new Error()`\n\n(and its subtypes), and `new Function()`\n\n.\n\n``` js\n-const obj=new Object();\n+const obj={};\n-const arr=new Array(1, 2, 3);\n+const arr=[1,2,3];\n-const err=new Error(\"Something went wrong\");\n+const err=Error(\"Something went wrong\");\n```\n\nThanks to @dylan-conway for the contribution\n\n`typeof undefined`\n\nchecks are now minified\n\n`typeof undefined`\n\nchecks are now minifiedBun's minifier now optimizes `typeof`\n\nchecks for `\"undefined\"`\n\n. 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.\n\n```\n// Input\nconsole.log(typeof x === \"undefined\");\nconsole.log(typeof x !== \"undefined\");\n\n// Minified output\nconsole.log(typeof x > \"u\");\nconsole.log(typeof x < \"u\");\n```\n\nThanks to @Jarred-Sumner and @dylan-conway for this change\n\n`onEnd`\n\nhook for bundler plugins\n\n`onEnd`\n\nhook for bundler plugins`Bun.build`\n\nnow supports the `onEnd`\n\nhook 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`\n\nobject. This is useful for post-processing, cleanup, or sending notifications.\n\n```\nawait Bun.build({\n  entrypoints: [\"./index.ts\"],\n  outdir: \"./out\",\n  plugins: [\n    {\n      name: \"onEnd example\",\n      setup(build) {\n        build.onEnd((result) => {\n          if (result.success) {\n            console.log(\n              `✅ Build succeeded with ${result.outputs.length} outputs`,\n            );\n          } else {\n            console.error(`❌ Build failed with ${result.logs.length} errors`);\n          }\n        });\n      },\n    },\n  ],\n});\n```\n\nThanks to @alii for the contribution\n\n`jsxSideEffects`\n\noption\n\n`jsxSideEffects`\n\noptionBy 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.\n\nA new option, `jsxSideEffects`\n\n, has been introduced to prevent this. When set to `true`\n\n, Bun will no longer mark JSX as pure, ensuring that components with side effects are always included in the final bundle.\n\nYou can enable this feature in your `tsconfig.json`\n\nor by using a command-line flag.\n\n```\n// tsconfig.json\n{\n  \"compilerOptions\": {\n    \"jsxSideEffects\": true\n  }\n}\n```\n\nThis ensures that code with side effects, like the example below, behaves as expected.\n\n``` js\n// component.jsx\nlet counter = 0;\nfunction MyComponent() {\n  counter++; // This side effect will now be preserved\n  return <div>Hello</div>;\n}\n\n// index.jsx\n<MyComponent />;\nconsole.log(counter); // Reliably logs 1\n```\n\n[Unused function and class names are now removed during minification](#unused-function-and-class-names-are-now-removed-during-minification)\n\nBun's bundler now removes unused function and class expression names when minifying (`--minify-syntax`\n\n). This matches esbuild's behavior and results in smaller bundle sizes.\n\nA new `--keep-names`\n\nflag has been added to preserve these names, which can be useful for debugging or for libraries that rely on `Function.prototype.name`\n\n.\n\n``` js\n// input.js\nconst myFunc = function myInternalName() {\n  // \"myInternalName\" is not used anywhere\n};\n\nconst myClass = class MyInternalClass {\n  // \"MyInternalClass\" is not used anywhere\n};\n\n// After `bun build --minify ./input.js`:\n//\n// const myFunc = function() {};\n// const myClass = class {};\n\n// To preserve the names, use `bun build --minify --keep-names`\n// or `keepNames: true` in your build configuration.\n```\n\nThanks to @dylan-conway for the contribution\n\n[Monitor event loop delay with ](#monitor-event-loop-delay-with-perf-hooks-monitoreventloopdelay)`perf_hooks.monitorEventLoopDelay()`\n\n`perf_hooks.monitorEventLoopDelay()`\n\nBun now implements the `perf_hooks.monitorEventLoopDelay()`\n\nAPI for Node.js compatibility. This function creates and returns an `IntervalHistogram`\n\nobject that samples the event loop delay in nanoseconds. You can use it to diagnose performance issues and understand your application's responsiveness.\n\n``` js\nimport { monitorEventLoopDelay } from \"perf_hooks\";\n\nconst histogram = monitorEventLoopDelay({ resolution: 20 });\nhistogram.enable();\n\n// Introduce a delay\nawait Bun.sleep(100);\n\nhistogram.disable();\n\nconsole.log(\"Event Loop Delay (ns):\");\nconsole.log(\"Min:\", histogram.min);\nconsole.log(\"Max:\", histogram.max);\nconsole.log(\"Mean:\", histogram.mean);\nconsole.log(\"50th Percentile:\", histogram.percentile(50));\nconsole.log(\"99th Percentile:\", histogram.percentile(99));\n\n// Reset for next measurement\nhistogram.reset();\n```\n\n`http.Server.prototype.closeIdleConnections()`\n\nis now implemented\n\n`http.Server.prototype.closeIdleConnections()`\n\nis now implementedThe `server.closeIdleConnections()`\n\nmethod from Node.js's `http`\n\nmodule is now implemented. This method immediately closes all sockets that are not currently handling a request, which is useful for gracefully shutting down an HTTP server without waiting for idle keep-alive connections to time out.\n\n``` js\nimport { createServer } from \"http\";\n\nconst server = createServer((req, res) => {\n  res.end(\"Hello, World!\");\n});\n\nserver.listen(3000, () => {\n  console.log(\"Server listening on port 3000\");\n\n  // On a shutdown signal (e.g. SIGINT)\n  process.on(\"SIGINT\", () => {\n    console.log(\"Closing server...\");\n\n    // Stop accepting new connections\n    server.close((err) => {\n      if (err) {\n        console.error(err);\n        process.exit(1);\n      }\n      console.log(\"Server closed.\");\n    });\n\n    // Forcefully close any idle keep-alive connections\n    // This allows the server.close() callback to fire sooner.\n    server.closeIdleConnections();\n  });\n});\n```\n\n`bun run`\n\nnow supports `--workspaces`\n\n`bun run`\n\nnow supports `--workspaces`\n\nIn the next version of Bun\n\n— Bun (@bunjavascript)\n\nThe --workspaces flag in bun run runs the package.json script in each workspace package[pic.twitter.com/sXJFwhnx79][September 7, 2025]\n\nThanks to @dylan-conway for the contribution\n\n[RFC 6455 compliant WebSocket client subprotocol negotiation](#rfc-6455-compliant-websocket-client-subprotocol-negotiation)\n\nBun's `WebSocket`\n\nclient now correctly implements subprotocol negotiation as specified in RFC 6455. When you instantiate a `new WebSocket()`\n\nwith an array of desired subprotocols, Bun will send them in the `Sec-WebSocket-Protocol`\n\nheader.\n\nThe server can then select one of these protocols to use for the connection. Bun correctly validates the server's choice and makes the selected protocol available on the `ws.protocol`\n\nproperty. If the server responds with an invalid protocol, or doesn't select a protocol when one is required, the connection is now correctly rejected.\n\nThis fixes a long-standing compatibility issue with popular libraries like `ws`\n\nand `obs-websocket-js`\n\n.\n\n```\n// server (which already worked fine):\nBun.serve({\n  port: 3000,\n  fetch(req, server) {\n    // Client is requesting \"chat\" and \"superchat\" protocols.\n    // We'll select \"chat\".\n    const success = server.upgrade(req, {\n      headers: {\n        \"Sec-WebSocket-Protocol\": \"chat\",\n      },\n    });\n    return success\n      ? undefined\n      : new Response(\"Upgrade failed\", { status: 500 });\n  },\n  websocket: {\n    open(ws) {\n      console.log(`Server: new connection with protocol \"${ws.protocol}\"`);\n    },\n  },\n});\n\n// Client code:\nconst ws = new WebSocket(\"ws://localhost:3000\", [\"chat\", \"superchat\"]);\n\nws.onopen = () => {\n  // `ws.protocol` is now correctly set to the protocol\n  // selected by the server.\n  // Before, this would be an empty string.\n  console.log(`Client: connected with protocol \"${ws.protocol}\"`); // \"chat\"\n  ws.close();\n};\n```\n\n[Override ](#override-host-and-other-headers-in-new-websocket)`Host`\n\nand other headers in `new WebSocket()`\n\n`Host`\n\nand other headers in `new WebSocket()`\n\nYou can now override special WebSocket headers like `Host`\n\n, `Sec-WebSocket-Key`\n\n, and `Sec-WebSocket-Protocol`\n\nwhen creating a new client-side `WebSocket`\n\nconnection. This is done by passing a `headers`\n\nobject to the `WebSocket`\n\nconstructor.\n\nThis is useful for advanced use-cases like connecting through proxies that require a specific `Host`\n\nheader, testing servers with specific keys, or implementing custom subprotocol negotiation. Bun will automatically handle generating required WebSocket headers if they are not provided.\n\n``` js\n// Bun now supports overriding special headers in the WebSocket client\nconst ws = new WebSocket(\"ws://localhost:8080\", {\n  headers: {\n    \"Host\": \"custom-host.example.com\",\n    \"Sec-WebSocket-Key\": \"dGhlIHNhbXBsZSBub25jZQ==\", // Must be a valid base64-encoded 16-byte key\n    \"Sec-WebSocket-Protocol\": \"chat, superchat\",\n\n    // This already worked:\n    \"X-Custom-Header\": \"MyValue\",\n  },\n});\n```\n\n[Connect to specific Redis databases with ](#connect-to-specific-redis-databases-with-bun-redisclient)`Bun.RedisClient`\n\n`Bun.RedisClient`\n\nBun's built-in Redis client, `Bun.RedisClient`\n\n, now supports specifying a database number directly in the connection URL, aligning with the standard Redis URI scheme. You can append `/db-number`\n\nto your connection string to connect to a specific database without manually sending a `SELECT`\n\ncommand.\n\n``` js\nimport { RedisClient } from \"bun\";\n// Connect to database #2\nconst client = new RedisClient(\"redis://localhost:6379/2\");\n\n// Set a key in DB 2\nawait client.set(\"foo\", \"bar\");\nconsole.log(await client.get(\"foo\")); // \"bar\"\n\n// Connect to the default database #0\nconst defaultClient = new RedisClient(\"redis://localhost:6379/0\");\n\n// The key \"foo\" will not be found in DB 0\nconsole.log(await defaultClient.get(\"foo\")); // null\n```\n\nThanks to @HeyItsBATMAN for the contribution\n\n`Bun.redis`\n\nnow supports `hget()`\n\n`Bun.redis`\n\nnow supports `hget()`\n\nBun's built-in Redis client now supports the `HGET`\n\ncommand. This provides a more ergonomic and performant way to retrieve a single field from a Redis hash, returning the value directly instead of a single-element array like `hmget`\n\n. For single-field lookups, `hget()`\n\nis approximately 2x faster than `hmget()`\n\n.\n\n``` js\nimport { redis } from \"bun\";\n\n// Old way: returns an array\nconst [value] = await redis.hmget(\"my-hash\", \"my-field\");\n\n// New way: returns the value directly\nconst value = await redis.hget(\"my-hash\", \"my-field\");\n```\n\n[Faster number handling in Bun's APIs](#faster-number-handling-in-bun-s-apis)\n\nBun's internal APIs that return numbers, such as `fs.statSync()`\n\n, `performance.now()`\n\n, and `process.memoryUsage()`\n\n, now use a more efficient number representation when the value is a whole number.\n\nPreviously, these values were always represented as double-precision floating-point numbers. Now, they can be represented as tagged 32-bit integers, which makes subsequent arithmetic operations on these values significantly faster in JavaScriptCore.\n\n```\n// Bun's APIs now return numbers in a more efficient format when possible.\n// Operations like this can be faster.\nconst stats = fs.statSync(file);\nconst size = stats.size; // This is now a tagged integer if it fits.\n```\n\n[Node.js compatibility improvements:](#node-js-compatibility-improvements)\n\n- Fixed: A\n`RangeError`\n\nexception in`child_process.spawnSync`\n\nwhen the`stdio`\n\noption was configured with`process.stderr`\n\nor`process.stdout`\n\n. This unblocks usage of tools like the AWS CDK. - Fixed: A bug where\n`socket.write()`\n\nfrom`node:net`\n\nwould incorrectly throw an exception when passed a`Uint8Array`\n\n. Now it allows passing`Uint8Array`\n\ns, matching Node.js behavior. - Fixed: A bug where\n`crypto.verify()`\n\nwould throw an error when a`null`\n\nor`undefined`\n\nalgorithm was passed for an RSA key. It now correctly defaults to`\"SHA256\"`\n\nto match Node.js behavior. - Fixed a bug where the N-API function\n`napi_strict_equals`\n\nincorrectly used`Object.is`\n\nsemantics instead of the`===`\n\noperator. This improves compatibility with native modules that rely on strict equality checks, such as`NaN !== NaN`\n\n. - Fixed a crash in the N-API function\n`napi_call_function`\n\nthat could occur when the`recv`\n\n(the`this`\n\nvalue) argument was a null pointer. - Fixed\n`napi_create_array_with_length`\n\nto correctly handle negative or oversized lengths, matching Node.js's behavior. - Fixed:\n`util.promisify(http2.connect)`\n\nnow resolves correctly, improving Node.js compatibility for the`http2`\n\nmodule. - Fixed: In\n`child_process`\n\n, the`stdin`\n\n,`stdout`\n\n,`stderr`\n\n, and`stdio`\n\nproperties are now enumerable to match Node.js behavior. This fixes compatibility with libraries like`tinyspawn`\n\nand`youtube-dl-exec`\n\nthat use`Object.assign`\n\non the child process object. - Fixed: Request body streaming when using\n`node-fetch`\n\nin Bun now works correctly, preventing large request bodies from being fully buffered in memory. - Fixed: A bug where\n`Buffer.from(string, 'utf-16le')`\n\nproduced incorrect output in rare cases. This improves Node.js compatibility. - Fixed: an incorrect assertion failure in N-API when\n`napi_reference_unref`\n\nis called during garbage collection. This improves compatibility with Node.js and fixes crashes in packages like`rolldown-vite`\n\n. - Fixed:\n`process.versions.llhttp`\n\nwas missing, which improves Node.js compatibility. - Fixed:\n`module._compile`\n\nis now correctly assigned to`require('module').prototype._compile`\n\n. - Fixed: A noisy, un-actionable warning for\n`async_hooks`\n\nis no longer printed to the console by default, especially when using React or Next.js. - Fixed:\n`crypto.randomInt`\n\nwas not calling the callback. Now it does. - Fixed:\n`new Buffer.isAscii(string)`\n\nnow correctly checks for ASCII; it was previously using the`isUtf8`\n\nimplementation by mistake. This did not impact`Buffer.isAscii(string)`\n\n, only`new Buffer.isAscii(string)`\n\n, which you probably shouldn't use anyway. - Improved: error message in\n`Buffer.concat()`\n\nwhen concatenating buffers larger than 4GB. A`RangeError`\n\nis now thrown with a descriptive message.\n\n[Bundler & minifier improvements:](#bundler-minifier-improvements)\n\n- Fixed: In\n`Bun.build`\n\n, the`onResolve`\n\nand`onLoad`\n\nplugin hooks now correctly run for entrypoint files, matching esbuild's behavior. (Thanks to @dylan-conway) - Fixed: Runtime plugins using\n`onResolve`\n\nnow correctly resolve dynamic`import()`\n\ncalls, which previously could fail with an`ENOENT`\n\nerror. (Thanks to @dylan-conway) - Fixed:\n`Bun.build`\n\nnow throws an`AggregateError`\n\nby default on build failures. To revert to the old behavior, set`{ throw: false }`\n\nand inspect the`success`\n\nproperty on the returned`BuildOutput`\n\n. (Thanks to @dylan-conway) - Fixed: A bug where standalone binaries created with\n`bun --compile`\n\nwould incorrectly include the executable's name as an extra argument in`process.argv`\n\n. This could cause argument parsing libraries like`node:util.parseArgs`\n\nto fail. - Fixed: An assertion failure in\n`bun build`\n\nthat could occur when using the`--compile`\n\nand`--bytecode`\n\nflags together. - Fixed: Bundler plugins can now intercept entry points with\n`onResolve`\n\n, fixing a bug that prevented the creation of virtual entry points. - Fixed: A bug where\n`build.module()`\n\nin a Bun plugin would fail to parse TypeScript syntax when using`loader: 'ts'`\n\n. - Fixed:\n`Bun.build()`\n\nwas missing the`splitting`\n\nproperty in its TypeScript types. - Fixed: On Windows, single-file executables created with\n`bun build --compile`\n\nno longer have an incorrect \"Original Filename\" metadata field set to \"bun.exe\". - Fixed: A regression on Windows where\n`bun build --compile`\n\nwould fail when using embedded resources or a relative path for`--outfile`\n\n. - Fixed: a memory leak in\n`Bun.plugin`\n\nwhere`onLoad`\n\nfilters using regular expressions would not be garbage collected, causing memory usage to grow over multiple builds. - Fixed: A bug causing non-deterministic module resolution for packages that ship both CommonJS and ES Module versions. This could lead to inconsistent builds and \"dual package hazard\" errors.\n- Fixed: an error when parsing\n`linear-gradient()`\n\nwith`turn`\n\nangle units. - Fixed: A bug where certain modules using top-level await were missing a\n`async`\n\nkeyword, causing a runtime error. - Fixed: A bug where\n`banner`\n\noption with`format: \"cjs\"`\n\nand`target: \"bun\"`\n\ncould produce a syntax error if`banner`\n\ncontained a shebang.\n\n[JavaScript runtime improvements:](#javascript-runtime-improvements)\n\n`Bun.YAML.parse`\n\nnow accepts`Buffer`\n\n,`ArrayBuffer`\n\n,`TypedArray`\n\ns,`DataView`\n\n, and`Blob`\n\nas input.- Fixed:\n`Bun.Cookie.isExpired()`\n\nnow correctly returns`true`\n\nfor cookies with an`Expires`\n\ndate set to the Unix epoch (`Thu, 01 Jan 1970 00:00:00 GMT`\n\n). - Fixed: an exception in\n`crypto.subtle.importKey`\n\nwhen importing RSA private keys with Chinese Remainder Theorem parameters. This resolves a compatibility issue with the`jose`\n\nJWT library. - Fixed: a bug that caused\n`fetch()`\n\nrequests with large bodies to fail with an`ECONNRESET`\n\nerror when using an HTTP proxy for an HTTPS connection. - Fixed: Errors thrown inside\n`HTMLRewriter`\n\nhandlers are now correctly propagated as catchable JavaScript errors, instead of causing a`[native code: Exception]`\n\nmessage or a crash. - Fixed: A reliabiltiy issue in\n`HTMLRewriter`\n\n- Fixed: an assertion failure when using the\n`BUN_INSPECT_CONNECT_TO`\n\nenvironment variable in a project that loads environment variables from a`.env`\n\nfile. - Fixed: a crash when using\n`Bun.secrets`\n\non Linux. - Fixed:\n`fetch()`\n\nthrowing a`Decompression error: ShortRead`\n\nwhen receiving an empty response with`Content-Encoding: gzip`\n\nand`Transfer-Encoding: chunked`\n\n. This also occurred with brotli and zstd in some cases. - Fixed: A bug where\n`structuredClone()`\n\nwould throw a \"TypeError: Unable to deserialize data\" when cloning nested objects or arrays containing a`Blob`\n\nor`File`\n\n. Additionally, the`name`\n\nproperty of`File`\n\nobjects is now correctly preserved after cloning. - Fixed: A bug causing error stack traces to be truncated, which made debugging more difficult.\n- Fixed: A bug causing\n`fetch()`\n\nto hang when the server responds with a`101 Switching Protocols`\n\nstatus, which is used to upgrade a connection to a WebSocket. fetch() in Bun continues to not support WebSocket connections, it now errors instead of hanging. - Fixed:\n`new WebSocket()`\n\nnow emits an`error`\n\nevent before the`close`\n\nevent when a connection handshake fails. Previously, only a`close`\n\nevent was emitted, which was inconsistent with browser behavior. `process.versions`\n\nnow displays semantic versions for`zlib`\n\nand`libdeflate`\n\ninstead of commit hashes.- Fixed: A regression causing\n`bun --watch`\n\nto crash when a file is deleted. - Fixed: A bug where\n`bun --watch`\n\nwould not correctly handle changes in swap files.\n\n[Bun.SQL bugfixes:](#bun-sql-bugfixes)\n\n- Fixed: A regression from Bun v1.2.21 impacting\n`DATABASE_URL`\n\noptions precedence in`Bun.SQL`\n\nconnection string parsing. - Fixed: A potential crash in\n`Bun.SQL`\n\nwhen closing a MySQL or PostgreSQL database connection.\n\n[Shell improvements:](#shell-improvements)\n\n- Fixed: A shell crash when using environment variable assignments in a pipeline, such as\n`VAR=val | command`\n\n. - Fixed: A regression from Bun v1.2.21 where certain commands would trigger an assertion failure on Windows.\n\n[bun install improvements:](#bun-install-improvements)\n\n- Fixed an internal data structure in\n`bun patch`\n\nto use one-based line indexing by default. - Fixed: a panic when installing a global package with\n`--trust`\n\nif it contained dependencies that were already trusted. - Fixed: A crash that could occur during\n`bun install`\n\nwhen applying a malformed patch file with out-of-bounds line numbers. - Fixed: A bug where\n`bun audit`\n\ncould hang indefinitely due to a cycle in the dependency graph has been resolved. - Fixed: A bug when extracting tarballs with unusual package names could produce an invalid temporary filename, particularly on Windows.\n\n[TypeScript types:](#typescript-types)\n\n- Fixed: Added missing types for\n`AbortSignal.aborted`\n\nand`RegExp.escape`\n\nto`bun-types`\n\n. - Fixed: Added missing TypeScript types for\n`Bun.YAML.parse`\n\n.", "url": "https://wpnews.pro/news/bun-v1-2-22", "canonical_source": "https://bun.com/blog/bun-v1.2.22", "published_at": "2025-09-14 22:54:53+00:00", "updated_at": "2026-05-22 20:45:04.949122+00:00", "lang": "en", "topics": ["developer-tools", "open-source"], "entities": ["Bun"], "alternates": {"html": "https://wpnews.pro/news/bun-v1-2-22", "markdown": "https://wpnews.pro/news/bun-v1-2-22.md", "text": "https://wpnews.pro/news/bun-v1-2-22.txt", "jsonld": "https://wpnews.pro/news/bun-v1-2-22.jsonld"}}