I don't understand why the git history has been pruned in this fork.
According to the first commit in this fork:
> Squashed as a single orphan commit — the original oven-sh/bun history
isn't relevant to this stripped fork and its shallow clone doesn't
push cleanly to a fresh remote.
IMHO it's always a bad decision to do that. Here, all commit authors are lost. The original history is always relevant.
Yeah, this is one thing you should absolutely never, ever do as a responsible developer. It makes future debugging much more difficult (destroys git blame) and also is a huge dump on previous contributors who don't get credit for their work in the fork. If solenopsys is serious about the fork he should redo it. Throwing away history willy-nilly is such a giant red flag that I think he will have trouble attracting any contributors.
Not a fork, but a new project that takes a subset of the old Bun code to create something new, meant to complement Bun.
“Cruller is not intended to replace Bun for development. It is a minimal, specialized runtime for executing production code. In any case, I do not want to throw away such a large codebase that has taken several years to build. It makes more sense to turn it into a convenient embeddable library that can be used throughout the Zig ecosystem.”
Wasn't the point of the Ship of Theseus precisely that establishing wether something is or isn't something else is at least complicated? Using it right after saying "X is still Y" kind of seems to make the opposite point.
The point here is that even though the water is murky about it's intrinsic identity, we know that it's still a particular ship with a particular back story, making at least it's extrinsic identity an immutable known. Fairly similar to how - most, if not all - complex living organisms continually gain and lose composing cells throughout their lives, yet their individual identities remain fixed: "I am X and this is my dog Y".
Similarly, a "fork" as we understand it in the context of software is this thing that, even though it's a modified copy, retains its extrinsic identity: "This software X was worked on in Y context, and is now being worked on in Z+ contexts". Same software, even if it gets a name change.
I hate that people git squash merges into dev, it always adds an extra layer of unnecessary ceremony when fixing your original branch, as opposed to just pulling the latest back into your original branch, then fixing the one line or whatever that was affected after merge, and now your git history is incompatible, so you have to delete your local branches because they're pointless now. Git squash should be done before your PR if you want to nuke dumb commits, but I prefer to have it all, if you want to find the key commits, tag them!
Yeah, I'm okay with this particular case to some degree, since its a completely different project, I guess I'm frustrated that I keep seeing projects adopting git squash because some guy somewhere has really terrible commit messages.
You never run a git blame or git bisect to find out when and under which circumstances a regression or bug was introduced, and why this specific change was made? That might work for a while on a personal project, but is essential in a team project. It's not uncommon that by fixing a bug you also accidentially undo an actually intended change. Doing some software archeology in the git history and tracing back the steps that led to the bug/regression usually prevents that sort of thing. You'd also want to notify the person who introduced the bug (and if this is a good and honorable chap, they'll fix the bug themselves).
Simple but pretty common use case: If you're ever looking at some pre-existing code and thinking "I don't really get why it's written like this?", you can get a lot out of looking through the git blame/history.
Often "weird design" is there for historic reasons around stuff like backwards compatibility. If your project has a well managed commit log, you can find the notes of whoever implemented it, possibly even with their motivation for doing so.
At the very least, you can find out who wrote that code and ask them about it.
That actually is helpful, but it would require a git history that actually makes sense. I rarely encounter well thought out git histories. For me its often just dev ramblings or 10 word commit messages
If I can choose "badly maintained history" and "no history" I'll choose the former every time. That's even less of a problem when Claude can do a first pass for you.
Because there will be a reason why the code was changed that introduced the bug. If you fix the bug you might inadvertently break a different piece of functionality.
A git commit gives you the reason for the change and the context of what other files were changed at the same time. I’ve found that invaluable.
> A git commit [ideally] gives you the reason for the change
FTFY ;) I broadly agree, but it's important to note that, in practice, Git commits are hit and miss: they might save you a lot of time if they are well-structured and described properly, but they might also completely fail to give you anything of value (for the problem you're facing at the moment). Turning Git history into a broadly useful artifact requires a lot of discipline from everyone working on a codebase over its lifetime.
It's never totally useless, but it's often less helpful than it could be.
Recently, I turned to JJ for this exact reason: crafting a meaningful change history is much easier there, especially if you need to retrofit it after you're done with the implementation. jj's split, squash, and describe are a joy to work with, also because the interactive version lets you easily split or squash hunks (selected changes in the same file).
Concrete example: yabridge is a tool to let Linux users run DAW plugins designed for Windows. Some changes to Wine (yabridge's main dependency) made yabridge stop working in 2024, and those Wine changes are not going to be undone as they advance progress on Wine's own bug list and test suite. When those changes were made, there wasn't a clear way to change the yabridge code to work with the modified Wine functions.
At the very least, if Wine and yabridge didn't keep a history of their code, you wouldn't even be able to download and build Wine 9.21 staging, when yabridge worked.
Every few weeks, a new dev will find this problem and look into fixing it. By having a history, this dev can always look back on the working implementation. Maybe one day there will be a series of function calls in the new Wine codebase that gets the same behavior that worked before? Maybe Wine adds a flag for yabridge that reintroduces the old functionality but retains for everyone else the changes they decided were necessary. Both avenues would fix the bug but from different ends.
(I understand Wine avoiding the flag solution: It's more to maintain just to help a single project, plus it introduces a conditional jump fail in the very active event handler and windowing subsystems affecting nearly every Wine user, and the development of Wine keeps moving, which could make a flag-based workaround redundant in the near future.)
I haven't opened my DAW in a few months. Last I knew, the problem is resolved for most users but not all, and there might have been a major breakthrough in April or May that still hasn't reached end users.
I don’t - Windows keeps a compatibility database for a reason. It seems inevitable that you’d need to maintain that too to keep apps working or drop support. The performance is a non-sequiter for a few reasons. Even in the hot path the conditional is going to get speculated away since the wine subsystem is uniquely instantiated per application. If you were really paranoid you could ship multiple binaries and select which ones to use dynamically at runtime. I suspect the bigger problem is one of maintenance - Microsoft does this with a huge budget and a huge team whose sole responsibility is maintaining that comparability. A community project is going to have to make more pragmatic choices.
Diagnosing why a bug happened is interesting. Sometimes it points to a communication shortcoming that the project/organization should strive to improve on. Of course, if you're slinging code with a few buddies, it might not matter.
In the worst/most paranoid case (xz) you might also want to know who planted a backdoor and where else they made commits to.
Checking git history is one of the first things I do when I find unfamiliar code or when I'm debugging something. Git history contains a lot of context that helps speed up the rest of the process
You've truly never come across a single thing you've gone to "fix" only to have it break stuff and then explained why it needs to stay that way in a commit message?
There are several possible reasons for that, but I'll just say it's a very common use case. It's actually the one of the original use cases for SCSs. How else could you revert to a prior commit?
If I'm taking a project in a completely different direction, with different people, I might not care about commit history very much. But I worry more from a licensing standpoint. Unless a project has a strict copyright re-assignment policy (uncommon) where all contributors sign over their copyright (not just contribute their "patch" under the designated license), the copyrYight history is lost or at best muddled.
Now, in practical terms, one can always go back to the original repo and find it. But if I was doing this in a corporate $DAYJOB, I'd keep the history just to be sure.
There seems to be some confusion here (including in the linked discussion?) about what this is. This is not continuing the development on the original Bun (Zig) codebase.
It is extracting a subset of that codebase for deployment purposes. The full version of Bun (presumably in Rust?) will continue to be used for actual development.
So it is not a replacement for Bun, but a supplement to it.
> Cruller is not intended to replace Bun for development. It is a minimal, specialized runtime for executing production code.
> In any case, I do not want to throw away such a large codebase that has taken several years to build. It makes more sense to turn it into a convenient embeddable library that can be used throughout the Zig ecosystem.
This seems pretty sensible to me. It's nice if the Zig ecosystem has an embeddable JS runtime.
I think there are quite a few high profile examples where the fork was successful (egcs comes to mind which eventually became the official gcc, also all the BSD flavours). And even when the fork ultimately isn't successful, it sometimes at least forces the original project to adapt (e.g. ffmpeg vs libav).
E.g. "it's difficult to make predicitions, especially about the future" ;)
PS: of course for this specific project I don't quite understand the reason. The original Bun was largely a line-by-line port of esbuild from Go to Zig, so it's not like the original codebase was a marvel of engineering to begin with...
I don't know that there's ever been a high-profile fork of a product acquired by such a fat, mealy, and genuinely unspooling parent as Anthropic's acquisition of Bun before.
But by all means I would love to hear some examples of that.
> My idea is to strip the system down as much as possible and leave only what is required for production.
> Development would be done using the full Bun runtime, while production would use its lightweight fork, Cruller. I do not have the resources of the Oven team to develop and maintain a massive general-purpose runtime, so I want to focus on specific production requirements.
I don't know about others, but I don't think I would deviate my development runtime from my production runtime so significantly. The chance for behavior that only rears its head in production is too high for my liking.
What makes Bun Bun is all the things that got removed from this project. Node is already powerful enough and well maintained. Why would anyone use this?
The developer is quite clear about not wanting to make Bun. They want to make a reusable JavaScript runtime for Zig. How would you execute a Node runtime in Zig?
That’s about the most basic imaginable implementation. Typically you use JavaScript runtimes like this to provide a plugin-like system for your static build that allows sandboxed customisation at runtime.
Take a look at the JavaScriptCore documentation to get a sense of what’s possible, it goes far beyond “piping the input”:
But what does bun bring to the table in that scenario? Why not interface with javascriptcore directly and skip the (unmaintained) middle man?
Bun provides the node standard library, I suppose, but you likely don't want it in a plugin system. Because the bulk of it is to deal with web requests, or to allow system-wide file/network/process access. So you're going to re-implement your own safe library anyway.
> But what does bun bring to the table in that scenario?
There's a middle ground between "raw C API" and "full Node-compatible runtime". It sounds like this project is attempting to use that middle ground: the Zig wrapper around JavaScriptCore, rather than the whole abandonware project.
As per another comment here:
> This is not continuing the development on the original Bun (Zig) codebase.
It is extracting a subset of that codebase for deployment purposes.
> The main design decision is to treat this as a runtime, not a general-purpose Bun replacement. A minimal launcher loads a pre-built entrypoint; features that require package installation, bundling, TypeScript transformation, or bun test are intentionally outside the scope.
The author is saying explicitly they don’t want to make a Bun replacement
Indeed it's surprising, given the zig compiler famously causes all developers who use it to merge into a single organism with a combined nervous system.
It seems you misunderstand what happened to Bun: Anthropic has burned some investor money for a PR stunt -- our LLM can port this -- and also to punish Zig which dared to ban LLM contributions by taking away a significant project from the ecosystem. It worked, Rust didn't dare to enact a similar ban.
Anthropic tried hard to port using their LLMs but their models were not trained on enough zig corpus hence failed and they blamed it on Zig's principles
Please re-read my comment, I didn't mention anything about Rust. (IK they later switched to Rust. A year ago no LLMs were good at rust, similar to zig today, however its different story now)
I can see why that's the case, given that Rust is that much more popular than Zig. I wonder whether there's a difference between LLMs reading code and writing. If reading code is easier than writing it, then it makes sense that Claude was able to port from Zig to Rust with good results.
One thing to point out is all the author's comments seem LLM generated and so does the README and the latest commit to the branch (large explanation in a comment and then change)..
You can point it out, but we should also mentioning that the author also points it out:
AI / LLM usage disclosure
AI was used as an engineering assistant for parts of the Zig 0.16 migration, build/debug investigation, and focused test work. The project scope, architecture decisions, review of changes, and build/test verification remain maintainer-directed. This is not a purely AI-generated project.
i dont see the point of this to be honest, if rust is actually better for bun why are you people just hating on it for no reason? a software doesnt have to be written in your favourite language for it to work.
bun was a sloppy project is zig and still sloppy in rust
> Bun stopped shipping a Zig-based runtime after 1.3.14 — the project moved on to a Rust rewrite. Cruller forks that last Zig-era Bun and ports it forward to Zig 0.16 instead of following Bun into its rewrite.
I might be missing something, but where does it mention why specifically they're interested in having this be Zig and not Rust?
> In any case, I do not want to throw away such a large codebase that has taken several years to build. It makes more sense to turn it into a convenient embeddable library that can be used throughout the Zig ecosystem.
I think it's the other way around. Bun is being ported from Zig to Rust for no significant benefit, but just for the sake of using AI. Bun doesn't gain any significant performance improvements. The codebase is now filled with unsafe blocks, which undermines many of Rust's safety guarantees. On top of that, it hasn't undergone enough real-world testing to ensure it works correctly.
Heroic effort, sifting through that code I mean, but frankly I would have started a new one from scratch, the only thing of value is the name/popularity of the original project.
According to the first commit in this fork:
> Squashed as a single orphan commit — the original oven-sh/bun history isn't relevant to this stripped fork and its shallow clone doesn't push cleanly to a fresh remote.
IMHO it's always a bad decision to do that. Here, all commit authors are lost. The original history is always relevant.