Buz - A drop-in replacement for Bun using modern Zig, with sub-1s incremental builds

8 min read Original article ↗

Buz


This is my WIP fork of Bun, based on the last commit before their Rust rewrite. It is still very early in its development and is nowhere near ready for production. I saw that a similar project had already been posted on Ziggit, so I am posting mine to avoid duplicating any development effort, though I have not looked at the other project as of this writing.

I have ported Bun to build with the current upstream Zig (with minor patches to get incremental rebuilds to work). The whole build graph is now in build.zig, including vendored sources of JavaScriptCore. This allows for sub-1s incremental builds, greatly improving the dev loop for the project.

The goal is to be a drop-in replacement for Bun, with a saner codebase. To that end, I have imported all the new tests from Rust Bun into the project, many of them covering new features and bug fixes. A lot of tests don’t pass yet, so this will be a treadmill of keeping up with upstream. But I am trying to deslop the codebase in the process, and keep reducing technical debt.

To that end, I’ve cut over 11,000 lines of completely dead code from Bun. I can’t think of another project whose codebase was so neglected as to reach 11K lines of dead code. I’ve also rewritten and modernized parts of the codebase, trying to rely more on Zig’s stdlib. In the process, countless bugs have also been fixed.

Supported Zig versions

The project has a slightly patched Zig master submodule, mostly regarding incremental builds. Upstream Zig at yesterday’s commit 2b1c663 should be able to build it just fine.

AI / LLM usage disclosure

Bun is the quintessential AI slop project at this point. Inheriting that is no easy task. I don’t think any human should sacrifice their sanity untangling this mess of 600K lines of slop code. For that reason, I will not be accepting any human-coded contributions until I deem the project to be in a sane enough shape. It will likely require most subsystems to be rewritten.

To this end, LLMs will be used extensively. But hopefully better development practices, with a human in the driver’s seat, and a focus on reducing technical debt and writing idiomatic Zig, mean that in a few weeks or months there will be a presentable codebase that serves as a drop-in replacement for Rust Bun 1.4.0. If you have access to Sol or Fable, you can help me get there faster.

Feel free to point out cases of the most egregious slop in the Bun codebase, and I’ll do my best to fix and modernize them. I am using this as a way to improve my own Zig skills. In the long term, I hope this becomes a codebase that is pleasant enough to maintain without LLM help.

2

Sounds like a plan.
I dont have Fable or Sol but I do want to chime in for support.

I’ve also built a JavaScript Runtime, and to be honest, I don’t think Zig or Rust is the most core part of Bun.

What really makes up Bun are C/C++ projects like JSC, uWebSockets, brotli, lol-html, tinycc, etc. Zig or Rust is just the glue.

That’s also why I’m not particularly interested in Jarred rewriting Bun in Rust—rewriting the glue doesn’t make much sense, and similarly, continuing to maintain a Zig fork doesn’t make much sense either.

So I’m curious if you have plans to rewrite these dependencies using Zig, and whether you have plans to implement a v8-compatible API for JavaScriptCore.

Since Bun’s performance is already excellent (regardless of code quality, its performance truly outpaces Node or Deno), the only two issues are stability and V8/N-API compatibility. The community would welcome a project that addresses these problems.

Thank you for the feedback!

I wish Bun was just glue, then it would be easy to clean up. There is a lot of glue, but most of it is real code, I would say about 3/4. For instance, the package manager is 40K lines of code. And of course all the Node APIs and Web APIs are implemented in Zig. Not to name 10-20 other native features it ships.

Just maintaining the current feature set, and keeping up with any new Bun features, and JSC updates, is probably going to be very hard. I wouldn’t mind rewriting some small dependencies once the project stabilizes, but I can’t see myself competing with large established projects like Brotli. At least not while this is a side-project. Zig is perfectly capable of building Brotli.

Bun already has some v8 compatibility. I’m glad I haven’t needed to look at that code yet. My understanding is that there are partial V8 API shims that make popular packages work, but nowhere near complete coverage. So that would remain the strategy going forward, unless a better solution comes up.

As for stability, is there anything in particular you have in mind that Jarred did poorly or that I could do better?

This seems a truly interesting project in terms of software “refurbishing” and I’m very happy to see that you were able to achieve the thing that to me was the biggest missed opportunity with the original maintainers: being able to get fast incremental builds.

If you want some more eyeballs on your project, I recommend writing a blog post where you demo the incremental rebuild speed!

As incremental nears full arch/os support, we’re (zsf) also going to make more noise about it, inclusive of demo videos.

A couple months ago, we had the same idea, and we have been building Home (forked Bun’s zig version) but we also created zig-js which is a JSC port. Lots of improvements still untouched, and benchmarks already are looking quite good.

But if anyone wants to help on zig-js, feel free! :smiley:

7

Hope I won’t get permanently banned for this :smiling_face_with_tear:

image

8

I think the idea is interesting. I question the use of LLM, to be honest. It is hard for me to not see the usage as inherently “sloppy”. I think it would be better to see if enough people are interested in maintaining a project like this and meet that need, instead of hoping the need is there and using LLM to spin it up. Just my opinion.

These are valid concerns.
As someone who is generally on Team Anti-LLM, the irony of fixing the AI slop… by using more AI… was not lost on me. That said, I do sympathize with OP in that they working with the hand that they were dealt when forking such a codebase that has those existing issues, the alternative being a monumental undertaking which essentially amounts to a complete rewrite.

It is mainly just sad that the project as devolved into such a state.

10

agreed. i just wonder if this should be done, then.

yup. i fear the same thing would happen to this project though, if there already isn’t a group of people willing to shepherd it.

11

Thank you! The build still uses mold for actual linking, which takes maybe 60% of the whole incremental time. There are 4 or 5 missing features in Zig’s own linker that are blocking its adoption by Buz. I will try to cut down on that list, while I’m sure the Zig team is actively working on implementing features. Once it works, it will cut the times further to <300 ms is my guess. At that point, it will be a very good showcase of Zig incremental builds.

12

Are there any of my commits that you feel have been sloppy? Any feedback would be appreciated.

I highly doubt it. Most forks like this die from the maintenance burden. You just can’t expect someone to sink in the thousands of hours it would take to clean this up by hand. But I’ll be happy to be proven wrong!

just driving by to say: this is the funniest thing ive seen in a while. thank you so much for making my morning

14

Oh, I love everything about this, well done.

What a great way to master Zig, have fun, and make new friends on the journey.

Its like the Boss level of zinglings challenges