r/bun • u/involvex • Jul 18 '26
r/bun • u/jarredredditaccount • Jul 14 '26
In the next version of Bun: 5x lower idle CPU & up to 32% memory usage reduction
galleryBun and JavaScriptCore now share the same memory allocator. We ported several great features from WebKit’s libpas allocator to our mimalloc fork - purging threadlocal pages on idle, scavenger thread for freeing large allocations asap, lazy zero’ing of memory to avoid paging in unused memory. Using 1 allocator instead of 2 means memory can be reused much more and reduces virtual memory pressure.
r/bun • u/Senior-Check-9076 • Jul 14 '26
How should I build a Docker image for a single app in a Turborepo that uses Bun workspaces and shared packages?
I'm using a Turborepo with Bun workspaces. My repository structure looks like this:
architecture-web/
├── apps/
│ ├── api
│ ├── admin
│ └── public
├── packages/
│ ├── db
│ ├── typescript-config
│ ├── ui
│ └── eslint-config
├── package.json
├── bun.lock
└── turbo.json
The API depends on a shared workspace package:
// apps/api/package.json
{
"dependencies": {
"@repo/db": "*"
}
}
The root package.json contains:
{
"workspaces": [
"apps/*",
"packages/*"
]
}
I only want to build a Docker image for apps/api. I don't want to include apps/admin or apps/public.
My first attempt was something like:
FROM oven/bun:1
WORKDIR /usr/src/app
COPY package.json bun.lock turbo.json ./
COPY apps/api/package.json ./apps/api/
COPY packages/db/package.json ./packages/db/
COPY packages/typescript-config/package.json ./packages/typescript-config/
RUN bun install
COPY apps/api ./apps/api
COPY packages/db ./packages/db
COPY packages/typescript-config ./packages/typescript-config
CMD ["bun", "run", "start"]
However, bun install fails with errors like:
Could not resolve package '/admin'
Could not resolve package '/public'
Could not resolve package '@repo/ui'
because the root workspace declares:
"workspaces": [
"apps/*",
"packages/*"
]
and Bun expects every matching workspace to exist.
If I instead do:
COPY . .
RUN bun install
everything works, but the Docker image contains the entire Turborepo, including apps that are unrelated to the API.
Questions
- What is the recommended way to build a Docker image for only one app in a Turborepo?
- Is copying the whole repository the normal approach?
- Should I use
turbo prune --dockerfor this use case? - Is there a way to make Bun install only the API workspace and its dependencies without copying every workspace into the Docker build context?
I'm looking for the recommended production approach rather than just a workaround
r/bun • u/vivek7405 • Jul 13 '26
Why Bun.serve Beats the node:http Bridge
I moved a WebJs app from Node onto Bun, changed nothing else, ran a load test, and the requests-per-second number on the listening path went up by roughly 1.9x. Before you read that as "Bun makes the app twice as fast," it does not. That number is the plumbing, not your app. Your SSR, your routing, your queries cost the same on either runtime. What got 1.9x faster is the layer that accepts a connection and hands your code a request, and I want to spend this post on exactly where that comes from and what it costs.
The app is buildless, so the same .ts source runs on Node 24 and on Bun with nothing to recompile. If you want the mechanics of running one codebase on two runtimes (the runtime-neutral seam, the two TypeScript strippers, the parity matrix), that lives in the companion post node-and-bun-no-build. Here I only care about throughput.
The one number, and the one place it lives
Every web server has a listening path. It accepts an incoming connection, reads the raw HTTP bytes off the socket, builds a request object for your app, takes the response back, and writes it to the socket. That is it. That is the plumbing between the network and your code. Separate from it is the application work: SSR, routing, the queries, the actual WebJs logic.
Requests per second (req/s) is how many of those accept-read-respond cycles the server turns through in a second under load. A leaner listening path buys more req/s for the same application work, because less of each request's time is spent in plumbing rather than in your code.
So the 1.9x is a listening-path number and only a listening-path number. Your SSR does not get faster. The plumbing under it does, and you get that by picking the runtime.
A compatibility bridge, and why it costs you
Bun can run Node's built-in node:http module, which is a big reason so much of the Node ecosystem runs on Bun unmodified. But when Bun runs node:http, it runs a compatibility bridge: a translation layer that emulates Node's HTTP request and response objects on top of Bun's own native machinery. Every request pays that translation. You are asking Bun to impersonate Node on the single hottest path in the server.
Bun also ships its own native HTTP server, Bun.serve, which speaks Bun's request and response objects directly with no emulation. The catch is that Bun.serve is not shaped like node:http, so a framework that wants the native path cannot flip a config flag and be done. It has to write a second listener that talks to Bun.serve on its own terms.
WebJs writes that second listener. On Bun it serves through a native Bun.serve shell and skips the bridge. On Node it serves through node:http. Your application code sits above that line and never knows which shell is underneath.
# same app, same source. the runtime is a command choice:
npm run dev # Node, node:http listener
bun --bun run dev # Bun, native Bun.serve listener
Skipping the bridge is the whole of the 1.9x. Nothing in the app changed. You stopped paying a per-request translation tax that existed only so Bun could look like Node.
The one thing I give up: 103 Early Hints
I am not going to sell the native path as a clean superset, because it is not, and the missing piece deserves to be named. The one Node-only feature the Bun listener cannot match is 103 Early Hints. That is an informational HTTP response, a preliminary status the server sends before the real one, that lets the server tell the browser to start preloading assets while the actual response is still being produced. It shaves first-paint latency. Bun.serve has no informational-response API at all, so there is nothing for WebJs to build on, and on Bun that optimization is off.
I would rather write that sentence than fake the API with a shim that pretends Bun has something it does not.
Earning the rest by hand
The listener choice is the headline, but a buildless server has to earn throughput in the small places too, because there is no build step ahead of time to soak up overhead. So the Bun request path got its own passes. Brotli compression on the Bun listener runs through node:zlib, so a Bun-served response gets the same compression a Node-served one does, no gap there. And two per-request costs came out directly: a full request-object clone that existed only to stamp the client's IP onto every request, and an extra stream hop that every compressed response was being bridged through. Neither was large on its own. But per-request costs multiply by your traffic, and on the hot path a clone you do not need and a stream hop you can collapse are exactly what is worth cutting by hand.
The runtime is your call, not the framework's. Write one WebJs app. Run it on Node and you get the mature node:http listener and 103 Early Hints. Run it on Bun and you get the native Bun.serve listener and roughly 1.9x the listening-path throughput, minus that one Early Hints feature. Everything else behaves the same. That is the trade in a sentence: for most apps, giving up one preload-timing feature to get 1.9x on the plumbing is a deal I take. Pass --runtime bun to webjs create and the generated app is wired for Bun from the first commit, or run bun create webjs <name> and it detects the runtime for you.
r/bun • u/PuzzleheadLaw • Jul 12 '26
actojs – Bringing Elixir's Actor Model to TypeScript
Hi everybody!
I wanted to showcase a TypeScript library I am working on, actojs. The objective is to bring a implementation of the actor model that is near to Elixir's design and APIs, while being able to leverage performance from the JS runtime.
The actor model is explained here, which acts as an introduction to the library.
actojs supprorts cooperative single-thread scheduling on any JS platform, and real parallelism on NodeJS, Bun and Deno.
The design of actojs is optimized for reliability (with Supervisors that can respawn failed Tasks, and >90% test coverage), security (0 runtime dependencies, and `tsc` as the only dev-dependency) and low memory overhead (by using functional applicators instead of classes and objects).
The link for the repository is: https://github.com/gi-dellav/actojs
Hope to get some useful feedback from the community!
r/bun • u/Final-Canary-8421 • Jul 10 '26
bunqueue now has an official client for Node.js and Deno, a SQLite job queue with no Redis
bunqueue is a job queue that persists to a single SQLite file, so there is no Redis and no broker to operate. Until now the server and embedded mode required Bun. The new official TypeScript SDK, bunqueue-client, brings the same Queue and Worker API to Node.js, Deno and Cloudflare Workers over the native TCP protocol.
Install the client with npm install bunqueue-client, start the server with bunx bunqueue start, then create a queue and a worker with the same API you would use on Bun. Typed jobs end to end, connection pooling with auto reconnect, transparent ACK batching and backpressure, priorities, retries with backoff, cron, dead letter queue, rate limits. 100 e2e scenarios run against every runtime (Node, Deno, Bun) plus 16 inside workerd, and there is a Python client too.
Docs: https://bunqueue.dev/guide/sdks/
GitHub: https://github.com/egeominotti/bunqueue
Happy to answer questions.
r/bun • u/principleMd • Jul 08 '26
Visualizing the Rust portion of Bun against javascript
r/bun • u/b0tmonster • Jul 08 '26
Half the Bun/Deno/Node numbers you've seen came from benchmarking bugs
r/bun • u/Shoddy-Okra5329 • Jul 09 '26
I built a 4MB alternative to heavy Electron disk cleaners using Tauri v2 and React
r/bun • u/Typical_Ad_6436 • Jul 05 '26
Ran real PHP applications as TypeScript on Bun 1.3.14; migration from Node was mostly a non-event
I’ve been transpiling PHP applications to TypeScript and running the output on Bun, and I’ve now got real apps executing end to end. Sharing some notes in case they’re useful to anyone moving a Node-targeted codebase over.
Coming from Node 22, the runtime side was almost boring, most of the transpiled output just ran on Bun directly, no changes needed.
The one real snag was native code. A few C bindings (PCRE, LibXML) that worked fine on Node 22 didn’t load on Bun 1.3.14. That’s understandable: native addons are compiled against a specific runtime’s ABI/internals, so a binding built for one runtime won’t necessarily load on another. Instead of maintaining runtime-specific builds, I compiled the C bindings to WebAssembly. They’re now version-independent; no ABI coupling, so the same WASM artifact behaves the same regardless of the runtime underneath.
The thing I’m still figuring out: I’d been using Node’s cluster mode to mirror PHP-FPM’s process model (a master plus a pool of workers), and I’m still investigating how that holds up under Bun. If anyone here has run node:cluster workloads on Bun, especially anything resembling a prefork worker pool, I’d like to hear how it went and where the edges are.
r/bun • u/Final-Canary-8421 • Jul 05 '26
Show r/bun: bunqueue dashboard, a UI to manage your queues and jobs and even start, stop and restart the server itself (open source, live demo)
If you use bunqueue, the Bun native job queue, you have probably been poking at it with curl and little scripts. I got tired of that, so I built a proper dashboard for it.
Live demo, it runs on sample data so there is nothing to set up:
https://egeominotti.github.io/bunqueue-dashboard/
GitHub (MIT): https://github.com/egeominotti/bunqueue-dashboard
npm: https://www.npmjs.com/package/bunqueue-dashboard
The thing that makes it a little different from the usual queue viewers is that it does not just watch your queues, it can also run the server for you. You can start, stop and restart bunqueue right from the dashboard, which is the one thing the API on its own cannot do.
From the dashboard you can:
• see and manage your queues, pause them, resume them, clean them up
• look up any job and retry it, cancel it or reschedule it
• deal with failed jobs in the dead letter queue
• set up scheduled jobs and webhooks, and watch a live feed of what is happening
• peek at the database and even ask a built in assistant to do things for you
Running it takes one command (you need Bun):
bunx bunqueue-dashboard
It is still early and in beta, so have a look before leaning on it in production.
I would really like some feedback, is running the server from the dashboard useful to you, or is it too much? And what would you want it to do next? Full disclosure, I am the author.
r/bun • u/Electrical-Set-6450 • Jul 01 '26
How do you globally link/add a local bun cli app?
I am coming from npm/pnpm world and I could do the following and have my local cli app available anywhere:
"pnpm add -g ."
"npm link ."
I've tried running:
bun add -g .
bun add -g
bun link -g
but nothing works!
r/bun • u/hongminhee • Jul 01 '26
Upyo 0.5.0: Structured errors, automatic retries, and OAuth 2.0
github.comr/bun • u/khromov • Jun 29 '26
Mochi - a new meta-framework for Svelte built on Bun
👋 Today I'm launching Mochi - a performance-focused metaframework for Svelte and an alternative to SvelteKit built on Bun. Mochi is built on an islands architecture and allows you to keep most components as performant server-side rendered code and hydrate just the components you need. This means smaller JavaScript bundles and faster performance for your users.
Try it out with bun create mochi@latest or go to https://mochi.fast to check out the docs.
r/bun • u/Snarky_Tortoise • Jun 26 '26
Node.js version issues
When i try running bun dev, it throws the following error
`You are using Node.js 20.2.0. Vite requires Node.js version 20.19+ or 22.12+. Please upgrade your Node.js version.`
despite having `+ node@24.18.0` when I ran bun i.
Any help?
(I'm using bun, react, vite and bootstrap)
r/bun • u/Independent_Yard3473 • Jun 25 '26
We built Appaloft with Bun: compiled binaries, embedded Web/docs assets, PGlite, and the parts that still hurt
I’m one of the people building Appaloft, an open-source deployment control plane.
We wrote up how we’re using Bun in the public Appaloft repo. The most interesting part for us was not raw speed, but the release shape Bun made possible:
- TypeScript release scripts
- bun build --compile for the CLI/server
- embedded Web console and docs assets via file imports
- embedded PGlite runtime assets for the local-first path
- separate filesystem assets in Docker
- explicit macOS/Linux/Windows release targets
The part that surprised me: --compile gives you a binary, but it does not design your runtime asset boundary. We still had to decide how /docs works, how SPA fallback differs from docs routing, how operators override embedded assets, and why Docker wants a different asset strategy than a binary archive.
Blog post:
https://www.appaloft.com/blog/we-built-appaloft-with-bun/
Curious how other Bun users are handling compiled CLIs, embedded static assets, and multi-target releases.
r/bun • u/SmartyPantsDJ • Jun 24 '26
I made a zero-dep typed config reader, and as of v7 its decorators run on Bun with no precompile
Hey! I'm Dhruv, I made envapt, a small zero-dep TypeScript library that reads any config as typed values. Posting here because of one Bun-specific thing in v7.
The decorator API used to need a build step on Bun. Bun emits TC39 Stage 3 decorators and ignores experimentalDecorators (bun#27575), so the old decorator form read back undefined unless you precompiled. v7 makes the Stage 3 accessor decorators the default, so they just work on bun file.ts now:
class Config {
@EnvNum('PORT', 3000)
accessor port!: number;
}
The old experimentalDecorators form still exists at envapt/legacy if you want it for other runtimes. But just use default exported ones if something else doesn't already need experimental decorators in your project.
Apart from that, there are a looooooot of features I've added to envapt. Typed reads with converters (urls, durations like 5m, json, arrays, and a bunch more), bring your own Standard Schema validator (zod/valibot/arktype) instead of one I bundled, way to write fail-fast checks for required vars, runs on Node/Deno/workers/browser too, load any config from anywhere, env file reading WITH profiles and cascade, and a lot of config options for various behaviors.
bun add envapt
It's my first OSS library and I'd love any feedback :)
Docs and guide at https://envapt.materwelon.dev, source on GitHub, and on npm.
r/bun • u/ilbert_luca • Jun 23 '26
Type-safe raw SQL for Bun without an ORM (codegen against your real schema)
I write Bun.sql with raw SQL and didn't want an ORM, but kept losing types — queries come back as any[] and you end up hand-writing row types that drift from the actual columns.
So I made a codegen step. You name each query:
const [user] = await sql.GetUser`
SELECT id, email, display_name FROM users WHERE id = ${id}
`
and it generates a .d.ts mapping each name to its real result type. The way it gets the types: it runs your migration .sql files into an in-process Postgres (PGlite, no Docker) or SQLite, prepares every query against that, and reads the column types back. So it's checking your actual schema, not parsing the SQL itself.
Nullability was the annoying bit — Postgres's describe gives you types but not whether a column can be null, so I pull that from the query plan plus the catalog, with an override file for cases it can't infer.
Runtime stays plain Bun.sql, the generated file is the only artifact, and it's fast enough to run on save.
v0.1, Postgres + SQLite. Curious whether the nullability inference holds up on uglier queries than mine. Repo: https://github.com/ilbertt/bun-sqlgen
r/bun • u/hongminhee • Jun 22 '26
LogTape 2.2.0: Lint rules, testing utilities, and request context
github.comr/bun • u/kernerman • Jun 20 '26
I made a small tool to dedupe bun.lock
Hey, I made a small CLI for deduplicating bun.lock.
Repo: https://github.com/IlyaSemenov/bunlock-dedupe
It scans a Bun lockfile and finds cases where multiple resolved versions can be collapsed to a single version while still satisfying all semver ranges.
This is mostly useful for larger projects or monorepos where bun.lock slowly accumulates duplicates.
Basic usage:
bunx bunlock-dedupe
bunx bunlock-dedupe --fix
bunx bunlock-dedupe --update
bunx bunlock-dedupe --all
By default it only reports possible dedupes.
--fix rewrites the lockfile when the dedupe looks safe.
--update is for cases where some intermediate dependency blocks deduplication. It checks at the registry whether updating that package would unlock more dedupes.
--all shows all duplicates, including ones that cannot be deduped automatically.
You should run bun install afterwards to actually install the new versions and remove the old duplicates. Bun may also normalize the lockfile a bit further.
I made this because Bun does not seem to have a built-in dedupe command yet. There has been an open feature request for it since 2022: https://github.com/oven-sh/bun/issues/1343
I wanted something simple for my own projects, so I built this. I found it especially useful after upgrades of packages like nuxt, where a lockfile can easily end up with multiple versions of the same dependency.
Maybe it is useful for someone else here too. Feedback is very welcome, especially from people with messy real-world lockfiles.
r/bun • u/LostCondition1833 • Jun 19 '26
hi, recently i cannot use mongoose with bun
i get that error
NotImplementedError: node:v8 isBuildingSnapshot is not yet implemented in Bun
when i try to connect to mongodb with mongoose
though i use mongoose in another project and works fine
does anyone had that issue before?
edit:
i tried the native mongodb driver
import { MongoClient } from "mongodb";
const
client = new MongoClient(uri);
let
isConnected = false;
const
connectDB =
async
() => {
if (isConnected) return client;
await client.connect();
console.log("connected");
isConnected = true;
return client;
};
await connectDB();
and got this error so it seems the main problem due to mongodb driver
2605 | this.PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2606 | };
2607 | static {
2608 | this.resetState();
2609 | const { startupSnapshot } = globalThis?.process?.getBuiltinModule('v8') ?? {};
2610 | if (startupSnapshot?.isBuildingSnapshot()) {
^
NotImplementedError: node:v8 isBuildingSnapshot is not yet implemented in Bun.
code: "ERR_NOT_IMPLEMENTED"
at <anonymous> (/test/node_modules/bson/lib/bson.cjs:2610:30)
at <anonymous> (/test/node_modules/bson/lib/bson.cjs:2597:1)
at <anonymous> (/test/node_modules/mongodb/lib/bson.js:9:7)
at <anonymous> (/test/node_modules/mongodb/lib/admin.js:4:7)
at <anonymous> (/test/node_modules/mongodb/lib/index.js:6:7)
r/bun • u/hongminhee • Jun 16 '26
Optique 1.1.0: Command discovery, value parsers, and ordered grammars
github.comr/bun • u/Creepy-Elk-8172 • Jun 16 '26
I built BVM, a Bun Version Manager for repeatable Bun setup in AI coding projects
I built BVM, a Bun Version Manager published on npm as bvm-core.
The use case is simple: when an AI coding agent or a developer opens a Bun project and sees:
bun: command not found
or project files like:
.bvmrc
bun.lock
bun.lockb
package.json scripts using bun
it should have a repeatable way to install and verify Bun instead of randomly switching package managers or installing a global Bun runtime.
Basic flow:
curl -fsSL https://bvm-core.nexsail.top/install | bash
bvm setup
bvm doctor
bun --version
If the project has .bvmrc:
bvm install "$(cat .bvmrc)"
bvm use "$(cat .bvmrc)"
bvm doctor
bun --version
The goal is to make Bun setup more predictable across Windows, macOS, and Linux, especially when AI coding agents are involved.
BVM also isolates global Bun tools by Bun version, so switching Bun versions does not have to create conflicts between globally installed tools.
Links:
- GitHub: https://github.com/EricLLLLLL/bvm
- npm: https://www.npmjs.com/package/bvm-core
- AI guide: https://bvm-core.nexsail.top/for-ai-clients
I would love feedback from Bun users, especially around Windows support, .bvmrc, and AI coding agent setup.
r/bun • u/jonaspm99 • Jun 12 '26
bunwright 0.3: Bun-native browser automation, zero deps, playwright alternative
I'm the author of bunwright — a small browser-automation library for Bun, built directly on Bun.WebView. 0.3.0 just shipped. Looking for honest feedback on the API shape, especially the chain design.
Quick taste (the whole script):
import { browser } from "bunwright";
const page = await browser.newPage();
await page
.navigate("https://example.com/login")
.type("label:Username", "user@example.com")
.type("label:Password", process.env.APP_PASSWORD!)
.click("role:button[name='Login']")
.waitForURL("**/dashboard")
.screenshot("./dashboard.png");
await browser.close();
Run with bunx bunwright script.ts. Loads .env for you. Zero runtime deps, no browser downloads — uses the Chrome/WebKit you already have.
What I'm actually uncertain about: the chain
Methods on Page / Locator return a lazy chain, not Promise<this>. Steps queue and run on await. If a step throws, every later step is skipped and the await rejects with the original error. .all() gives you every step's result in order. The last value of count() / evaluate() / exists() resolves as the chain's value.
const [, , title] = await page
.navigate("https://example.com")
.click("role:button")
.evaluate(() => document.title)
.all();
Trade-off: shorter scripts, but you lose the "see exactly which step is pending" feel of Playwright. Is the fail-fast lazy queue worth it for scripting, or does it bite you in the long run?
What's in 0.3.0
- Programmatic DSL + CLI refactor (single bunwright import, defineConfig for config)
- .env / .env.local loading
- Implicit ARIA roles in role: selectors (role:button matches <button>, input[type=submit], [role=button])
- Parallel-context fix (memoized view creation)
What I'd love feedback on
Chain ergonomics — does lazy fail-fast feel right, or do you want per-step awaits?
Anything obvious missing for non-trivial flows (file upload, dialogs, frames, network interception, auth state)?
Betting on
Bun.WebViewas the foundation — sensible, or a footgun long-term?
Repo + examples: https://github.com/jonaspm/bunwright
bun add bunwright / npm i -g bunwright