Impact Score: 5/10
bun v0.0.83
Source available โ automated, not human-reviewed
Component: bun ยท Channel: stable. Automated analysis, not a compatibility certification. How this works.
Analysis updated: 2026-11-01.
โก Executive Summary (TL;DR)
Bun bun-v0.0.83. Source highlight: Having trouble upgrading?
Who Does This Impact? (Role-Based Analysis)
๐ป Software Engineers & Devs
Check the source notes against the package and APIs you use before upgrading.
๐ Product & Engineering Leads
Use the documented changes to assess relevance to your product; release frequency alone is not a quality measure.
โ๏ธ DevOps & Security
Verify the target version, runtime requirements and rollback procedure in the official documentation.
โจ New Features & Capabilities (1)
- @adaptive for replacing `"wrangler@beta"` with `"wrangler"` in the examples for `bun add`
โก Performance & Enhancements (1)
- @kriszyp for tons of helpful feedback on how to improve Node-API support in bun
๐ง Bug Fixes & Patches (1)
- `Buffer.from(arrayBuffer, byteOffset, length)` now works as expected (thanks to @kriszyp for reporting)
๐ View Raw Release Notes (Original Developer Log)
To upgrade:
```bash
bun upgrade
```
<details><summary>Having trouble upgrading?</summary>
You can also try the install script.
```bash
curl https://bun.sh/install | bash
```
</details>
Thanks to:
- @kriszyp for tons of helpful feedback on how to improve Node-API support in bun
- @evanwashere for the idea & name for the `CFunction` abstraction
- @adaptive for replacing `"wrangler@beta"` with `"wrangler"` in the examples for `bun add`
- @littledivy for adding a couple missing packages to the build instructions
## `bun:sqlite`
`bun:sqlite` is a high-performance builtin [SQLite](https://www.sqlite.org/) module for bun.js.
It tends to be around 3x faster than the popular [`better-sqlite3`](https://github.com/JoshuaWise/better-sqlite3) npm package
<img width="738" alt="image" src="https://user-images.githubusercontent.com/709451/168459263-8cd51ca3-a924-41e9-908d-cf3478a3b7f3.png">
Note: in the benchmark I tweeted earlier, `better-sqlite3` always returned arrays of arrays rather than arrays of objects, which was inconsistent with what `bun:sqlite` & deno's x/sqlite were doing
### Usage
```ts
import { Database } from "bun:sqlite";
const db = new Database("mydb.sqlite");
db.run(
"CREATE TABLE IF NOT EXISTS foo (id INTEGER PRIMARY KEY AUTOINCREMENT, greeting TEXT)"
);
db.run("INSERT INTO foo (greeting) VALUES (?)", "Welcome to bun!");
db.run("INSERT INTO foo (greeting) VALUES (?)", "Hello World!");
// get the first row
db.query("SELECT * FROM foo").get();
// { id: 1, greeting: "Welcome to bun!" }
// get all rows
db.query("SELECT * FROM foo").all();
// [
// { id: 1, greeting: "Welcome to bun!" },
// { id: 2, greeting: "Hello World!" },
// ]
// get all rows matching a condition
db.query("SELECT * FROM foo WHERE greeting = ?").all("Welcome to bun!");
// [
// { id: 1, greeting: "Welcome to bun!" },
// ]
// get first row matching a named condition
db.query("SELECT * FROM foo WHERE greeting = $greeting").get({
$greeting: "Welcome to bun!",
});
// [
// { id: 1, greeting: "Welcome to bun!" },
// ]
```
There are more detailed docs in [Bun's README](https://github.com/Jarred-Sumner/bun#bunsqlite-sqlite3-module)
`bun:sqlite`'s API is loosely based on [@joshuawise](https://github.com/JoshuaWise)'s [better-sqlite3](https://github.com/JoshuaWise/better-sqlite3)
## New in `bun:ffi`
**`CFunction`** lets you call native library functions from a function pointer.
It works like `dlopen` but its for cases where you already have the function pointer so you don't need to open a library. This is useful for:
- callbacks passed from native libraries to JavaScript
- using Node-API and bun:ffi together
```ts
import {CFunction} from 'bun:ffi';
const myNativeLibraryGetVersion: number | bigint = /* Somehow you got this function pointer */
const getVersion = new CFunction({
returns: "cstring",
args: [],
// ptr is required
// this is where the function pointer goes!
ptr: myNativeLibraryGetVersion,
});
getVersion();
getVersion.close();
```
**`linkSymbols`** is like `CFunction` except for when there are multiple functions. It returns the same object as `dlopen` except `ptr` is required and there is no path
```ts
import { linkSymbols } from "bun:ffi";
const [majorPtr, minorPtr, patchPtr] = getVersionPtrs();
const lib = linkSymbols({
// Unlike with dlopen(), the names here can be whatever you want
getMajor: {
returns: "cstring",
args: [],
// Since this doesn't use dlsym(), you have to provide a valid ptr
// That ptr could be a number or a bigint
// An invalid pointer will crash your program.
ptr: majorPtr,
},
getMinor: {
returns: "cstring",
args: [],
ptr: minorPtr,
},
getPatch: {
returns: "cstring",
args: [],
ptr: patchPtr,
},
});
const [major, minor, patch] = [
lib.symbols.getMajor(),
lib.symbols.getMinor(),
lib.symbols.getPatch(),
];
```
`new CString(ptr)` should be a little faster due to using a more optimized function for getting the length of a string.
## require.resolve()
Running `require.resolve("my-module")` in Bun.js will now resolve the path to the module. Previously, this was not supported.
In browsers, it becomes the absolute filepath at build-time. In node, it's left in without any changes.
Internally, Bun's JavaScript transpiler transforms it to:
```js
// input:
require.resolve("my-module");
// output
import.meta.resolveSync("my-module");
```
You can see this for yourself by running `bun build ./file.js --platform=bun`
## `"node:module"` module polyfill
Node's [`"module"`](https://nodejs.org/api/module.html) module lets you create require functions from ESM modules.
Bun now has a polyfill that implements a subset of the `"module"` module.
Normally `require()` in bun transforms statically at build-time to an ESM `import` statement. That doesn't work as well for Node-API (napi) modules because they cannot be statically analyzed by a JavaScript parser (since they're not JavaScript).
For napi modules, bun uses a dynamic require function and the `"module"` module exports a way to create those using the same interface as in Node.js
```js
import { createRequire } from "module";
// this also works:
//import {createRequire} from 'node:module';
var require = createRequire(import.meta.url);
require.resolve("my-module");
// dynamic require is supported for:
// - .json files
// - .node files (napi modules)
require("my-napi-module");
```
This is mostly intended for improving Node-API compatibility with modules loaded from ESM.
As an extra thing, you can also use `require()` this way for .json files.
## Bun.Transpiler โ pass objects to macros
`Bun.Transpiler` now supports passing objects to macros.
```ts
import { Transpiler } from "bun";
import { parseCookie } from "my-cookie-lib";
import { Database } from "bun:sqlite";
const transpiler = new Transpiler();
const db = new Database("mydb.sqlite");
export default {
fetch(req) {
const transpiled = transpiler.transformSync(
`
import {getUser} from 'macro:./get-user';
export function Hello({name}) {
return <div>Hello {name}</div>;
}
export const HelloCurrentUser = <Hello {...getUser()} />;
`,
// passing contextual data to Bun.Transpiler
{
userId: parseCookie(req.headers.get("Cookie")).userId,
db: db,
}
);
return new Response(transpiled, {
headers: { "Content-Type": "application/javascript" },
});
},
};
```
Then, in `get-user.js`:
```js
// db, userId is now accessible in macros
export function getUser(expr, { db, userId }) {
// we can use it to query the database while transpiling
return db.query("SELECT * FROM users WHERE id = ? LIMIT 1").get(userId);
}
```
That inlines the returned current user into the JavaScript source code, producing output equivalent to this:
```jsx
export function Hello({ name }) {
return <div>Hello {name}</div>;
}
// notice that the current user is inlined rather than a function call
export const HelloCurrentUser = <Hello name="Jarred" />;
```
## Bug fixes
- `Buffer.from(arrayBuffer, byteOffset, length)` now works as expected (thanks to @kriszyp for reporting)
## Misc
- Receiving and sending strings to Node-API modules should be a little faster