Cruller Strips Bun Down to Zig 0.16: Production Runtime or Hype?

Lede

Cruller is a fork of the last Zig‑based Bun release, trimmed to the bits needed to run pre‑built JavaScript servers and ported to vanilla Zig 0.16. For SaaS operators tired of lugging Bun’s kitchen‑sink dev toolchain into production, the promise is a smaller, faster runtime that still speaks HTTP/1‑3, WebSockets, and fetch.

The reality

Under the hood Cruller keeps JavaScriptCore, Bun.serve, HTTP/1‑3, WebSockets, the fetch API, Blob, Request/Response, static file serving, and the module resolver for CJS/ESM entrypoints [1]. It deliberately excises the package manager, bundler/transpiler, shell, test runner, most CLI commands, N‑API, SQL clients, archive support, and other development‑only subsystems [1]. The result is a binary about 73 MiB on Linux x64, roughly 18 % smaller than the official Bun 1.3.14 build (≈88.5 MiB) [2]. Performance on the V8 Crypto benchmark shows parity with Bun, and the project reports passing Zig semantic checks, release builds, CJS/ESM entrypoint tests, Node‑path tests, and a basic Bun.serve + fetch() smoke test [2].

The port’s main engineering win is decoupling the runtime from Bun’s patched Zig build graph. Cruller now uses a vanilla Zig 0.16 build, adds compatibility shims for API changes since Zig 0.15, and embeds generated code so release builds stay portable instead of pulling JS from the build directory at runtime [1]. The project explicitly positions itself as a runtime only: development should still happen with the full Bun toolchain, while Cruller executes the pre‑built output [1].

The pain point

For teams that already bundle and transpile JavaScript in CI, the dev‑tool overhead in production is pure waste: larger attack surface, longer cold starts, and unnecessary licensing friction. Cruller’s trimmed footprint promises to shave a few megabytes off container images and reduce the attack surface by removing the package manager and bundler—components that have historically been sources of supply‑chain risk [1]. In environments where every megabyte counts (edge functions, serverless containers, or IoT gateways), an 18 % size cut can translate to lower egress costs and faster start‑up times.

However, the savings are modest if your pipeline already strips Bun down manually. Many shops already run bun build or bun bundle and ship only the generated JavaScript, leaving the Bun binary itself as a thin wrapper. In those cases the real win is not size but operational simplicity: a single binary that knows how to serve HTTP/3 and WebSockets without needing Node.js or Deno runtimes. The trade‑off is you lose Bun’s convenient dev‑time features—hot reloading, integrated test runner, and the bpm package manager—so you must rely on external tooling for those tasks [1].

Failure modes

Cruller is still a work‑in‑progress. The project’s own notes admit that the code‑generation step still depends on an installed Bun because the remaining generators are TypeScript [1]. Until those generators are ported to Zig, a full bootstrap requires Bun on the build machine, which undermines the promise of a Bun‑free pipeline. Additionally, the runtime only supports Linux x64 and Zig 0.16.0; Windows, macOS, and ARM builds are untested [2].

Teams that rely on Bun’s N‑API for native modules will find those missing, as Cruller deliberately omits N‑API support [1]. Finally, while the V8 Crypto benchmark shows parity, real‑world workloads that stress the JavaScriptCore garbage collector or make heavy use of Bun’s SQLite or zip APIs will hit unimplemented features.

The blueprint

If you’re evaluating Cruller for production, start with a concrete checklist:

  1. Audit your bundle – ensure all dependencies are already bundled/transpiled and that you don’t need Bun’s package manager, test runner, or N‑API at runtime.
  2. Validate the binary – pull the latest Cruller release from GitHub, run zig build -Drelease-safe on a Linux x64 CI agent, and confirm the built binary passes your internal Bun.serve + fetch smoke tests [2].
  3. Measure the impact – compare container image size, cold‑start latency, and request‑per‑second numbers against your current Bun‑based baseline. Expect roughly an 18 % disk‑size reduction and comparable throughput for HTTP‑heavy workloads [2].
  4. Plan for gaps – if you need SQL, ZIP, or native modules, either implement them in Zig yourself or keep a separate Bun‑based service for those workloads.
  5. Lock the toolchain – pin Zig 0.16.0 in your CI and vendor the Cruller repository; the project’s reliance on a vanilla Zig build graph means future Zig upgrades will require a new porting effort.

For teams already invested in Bun’s developer experience, Cruller offers a low‑risk way to shrink production footprints without abandoning the familiar API. For everyone else, it’s a reminder that the best runtime is often the one that leaves the unnecessary bits behind.

Sources

  1. Cruller: Bun's Zig Runtime, Continued on Zig 0.16
  2. Cruller: Bun's Zig Runtime, Continued on Zig 0.16
  3. Cruller: Bun's Zig Runtime, Continued on Zig 0.16