Rewriting Bun in Rust
bun.com568 points by afturner 12 hours ago
568 points by afturner 12 hours ago
Article did a decent job of showing discipline and care and human involvement to assert the automated rewrite was done diligently, as best as it can be when using AI for it. I does make me feel a bit more comfortable about it.
As an aside, I don't know why anyone would not want to use a memory-safe (and possibly race-safe) language in 2026. Rust gives you that in a performant package, so if you are turned off by GCs and immutability for performance reasons, you still have the option to use Rust.
I can understand when you need the absolute best performance and you decide to drop to down to C++, and I also relate with just personal preference, but beyond those it seems a no brainer to me.
> As an aside, I don't know why anyone would not want to use a memory-safe (and possibly race-safe) language in 2026.
The rust compiler is very slow. The best way to speed it up appears to be organizing a codebase in many crates. This is not preferable ergonomics to many. Beside that, for many problems, a garbage collector eliminates a large amount of defects (including the ones stated in the article) without any added friction, whereas Rust asks that you think in terms of ownership. This is not preferable ergonomics to many.
I realize what I'm saying above, while true, doesn't give a clear example. Many gamedevs would rather iterate with a language that is lower friction, not only because game code is finnicky (like frontend UI code) but because the build process can be unique. Many gamedevs prefer to iterate with hot-reloading, and asking them to use a slower compiler is asking them to accept greater latency in that cycle.
I do not claim that these reasons apply to everyone.
Game engines are typically in two languages, one for the engine itself and one for scripting. That even goes for Unity: in Unity, C# is a significantly more powerful than average scripting language (for lack of a better term), but the engine itself is still C++.
That's not to say that you couldn't write a commercial game engine with something like C# that stands shoulder-to-shoulder with unity and unreal, but it doesn't seem like anyone has attempted to do so. Maybe it's the decompilation fear.
Also, it would continue to make sense to use a scripting language alongside Rust.
> That's not to say that you couldn't write a commercial game engine with something like C# that stands shoulder-to-shoulder with unity and unreal, but it doesn't seem like anyone has attempted to do so.
Stride should mostly fit the bill: https://github.com/stride3d/stride
Their homepage: https://www.stride3d.net/
Even the physics engine they use is in C#: https://github.com/bepu/bepuphysics2
Not a very popular game engine (never got the attention that the likes of Godot did), but it's nice to work with! It’s up there with Stride in regards to the “indie” game engines I like, maybe alongside jMonkeyEngine (since you typically don’t see that many Java game engines either).
As someone who has almost no familiarity with game engines, it seems the success of this port was largely possible due to a comprehensive test suite written in a runtime agnostic way. What might be the equivalent test suite implementation required to successfully port a game engine to another language?
Gosh, I don't think any game engines have particularly good test suites at all. GoldSource and Source are the only ones that I have any real experience with and neither seems to have anything (Source may have a handful of things but nothing approaching baseline let alone comprehensive).
I have no idea how game devs handle big refactors other than lots of manual testing.
> Gosh, I don't think any game engines have particularly good test suites at all.
What? I do understand that a CRUD app with little to no logic do not focus on test.
But any kind of engine.. i can not understand that it's not a priority? In general I'm not a big fan of unit test on simple websites, they do not give any real value compared to effort
But I remember working on a complex codename. It was extremely important to have close to 100% unit test in the core part. Saved me a lot.
A game engine has a vast space of possible outputs, all of which will be considered good enough.
Its primary output is pixels and sound. Those are hard to test in a reasonable way. Screenshot testing is useless in a codebase where most of the changes are about making the pixels prettier.
One option would be to have an input replay alongside captured outputs (audio visual), at some fixed framerate. Capturing intermediates (scene graph etc.) would probably also be valuable, as that could help nail down why something is failing.
Or you could do it [as I recall the project being called] the scientist way. You still have the old code, so you could replay inputs against each and compare. Probably more realistic because uncompressed video would be a ridiculously huge dataset. This would be more resilient in the face of testing hardware and driver drift.
Historically game engines are the worst offenders when it comes to unit testing. I'm not sure if that's still the case - but that's why I erred on the side of integration tests.
Box3D just showcased some stuff including deterministic replays. If you wanted to port that, you could probably import the replay and make sure it plays back the same way in your new language. I think it captures the inputs and forces applied, not the pixels.
I suppose rendering is a component of a game engine too though, not just physics. I don't know how to do that reliably. Even if you captured pixels, it'd be annoying. If you've ever tried doing screenshot based diffing on web you will know that slight changes in aliasing in Chrome bugger everything up. Things that should be equivalent randomly aren't but not in a way that any human would care.
UE 5 doesn’t come with a scripting language even though there is blueprints which a node editor easy enough to be used by non dev. Studios like embark (The Finals, ARC Raiders) have been successful integrated AngelScript in UE 5 and use it in these games. UE 6 will see the appearance of Verse: the scripting language used for Fortnite (and the end of blueprint at some point). At first I was sad to see yet another language but it is worth looking at the doc to see why and how it makes a lot of sense.
> The rust compiler is very slow.
It's not “very slow”, that's a tired meme. It's slower than it could/should, but complaining about rustc being “very slow” is a clear misrepresentation, especially when everybody seems to have been fine with tsc's historical performance for instance. It could be nice if it was faster indeed, but people claiming it's “very slow” are just showing they never worked with it.
> The best way to speed it up appears to be organizing a codebase in many crates. This is not preferable ergonomics to many.
In this context (where you don't plan on publishing you stuff on crates.io) a “crate” are just a directory at the root of your repo, the ergonomic impact is literally zero.
Why do you think it is not slow? As far as I know the only language that compiles slower is C++, and even then the compilation speeds between c++ and rust seem to be comparable. I believe c, Fortran, zig, C#, Java and golang are all faster compiling languages. That makes rust pretty slow in my book. I get that it doesn’t bother everyone, but that doesn’t change the facts.
> Why do you think it is not slow?
The average cargo check for the projects I've worked on, usually finish in less than 1 second, with `cargo build` completing in a single digit second (often below 2s), it's not slow by any means.
> I believe c, Fortran, zig, C#, Java and golang are all faster compiling languages.
Sure, but the difference between type checking is 10ms and type checking in 500ms is barely noticeable for a human being anyway, despite the x50 difference.
> That makes rust pretty slow in my book.
“Slow” is a perceptual thing. It doesn't matter if it's slower in absolute benchmark performance. If it doesn't slow you down in your work it's not “slow”.
> As far as I know the only language that compiles slower is C++
Typescript's compiler is much slower than Rust's, but it's plenty fast enough for most people and you almost never see complains about it because it mostly doesn't matter outside of pissing contests.
Typescript's compiler is much slower than Rust's, but it's plenty fast enough for most people and you almost never see complains about it because it mostly doesn't matter
But you have to compile Rust code to run it. You can run TypeScript code without type-checking it. That’s a massive difference in the development workflow.
The new TSC, supposedly 10x faster, will be very pleasant to have but not as much of a game-changer as you might expect. A 10x faster Rust compiler would be incredible.
> But you have to compile Rust code to run it. You can run TypeScript code without type-checking it. That’s a massive difference in the development workflow.
And yet I'm waiting for TSC every day while almost never thinking about rustc…
> The new TSC, supposedly 10x faster, will be very pleasant to have but not as much of a game-changer as you might expect.
It will be very nice, but I don't expect it to be a game changer, tsc isn't fast but it's fast enough to get the work done, the annoyance is there but it's objectively minimal. Anything else is pointless internet language war.
> A 10x faster Rust compiler would be incredible.
For development? Not really, not for me at least. Against the endless rants about rustc's performance on HN, absolutely.
Actually it is possible to make C++ compile faster than Rust, because the ecosystem is more friendly towards binary libraries, then besides incremental compilation, you can also get incremental linking.
Additionally there are ways to have interactive code reloading, e.g. Visual Studio and Live++.
Or even a proper REPL, ROOT, CINT, Xeus.
Naturally all things that Rust could also have, only it hasn't been the focus and there are several decades to catch up.
It depends on what you're comparing it to. It is indeed very slow when compared to a C compiler, or a zig compiler, or even a Java compiler. C++ can be comparable, or slower, or faster, depending on the C++ features used.
Sure, maybe rustc's performance compares favorably to how tsc used to be, but that's not the benchmark most Rust developers (such as myself, for more than 10 years now) care about.
> a “crate” are just a directory at the root of your repo, the ergonomic impact is literally zero.
Nonsense. That's another Cargo.toml to maintain, and another place you might need to add/remove dependencies, and you have to manage the dependency tree among your sub-crates. The ergonomic impact is absolutely not literally zero, and I'd even say it's enough to be annoying.
As far as I'm concerned, I already hate the write-compile-run cycle, any further slowdown in that irritates me exponentially.
I am using Rust since 2016 productively... before I dabbled with it.
Rust is not compiling any slower than a comparable C++ codebase for me.
It is compiling much slower than a managed language like Kotlin, C# etc. though. Which is an unfair comparison anyway.
The problem with e.g. gamedev is the iteration cycles. It's very creative work and not so much your average engineering job (apart form game engine dev).
But again, that's an unfair comparison, because even in Unity and many if not most other game engines, there is a scripting language that is used for most of the game logic, that doesn't need hyper performance...
Still, when compared to such languages, Rust indeed does compile slowly AND one has to say: Rust is selling itself not only as a safe, blazingly fast systems programming language these days, but it also is used for its type system etc. and then, when you come from a managed language, compile times really suck.
(Although debug builds are better, they are not an option for game dev for example, because the binary is just too slow then... 200fps vs. 20 :X)
As much as I like Rust,
> In this context (where you don't plan on publishing you stuff on crates.io) a “crate” are just a directory at the root of your repo, the ergonomic impact is literally zero.
Is not true, you can't have circular out of crate dependencies. This often means you now need a third crate that's a trait crate, but then you can't implement external traits on external types, so you need bridge crates, and so on.
Rust's limitation of performance requiring lots of crates indeed has real impacts on projects beyond simple hello worlds or trivial cli apps.
Considering it to be a zero impact issue is rather reductive, even in the context of the language's design principles itself.
Rust for all it's good sides has had a lack of interest from core team and energy to drive real valuable changes beyond the nightly blockers into stable, or maybe they are working real hard and the boulders are so hard to move that we can't see any change looking outside in.
Is it justified after the gargantuan effort that was merging Async and GATs? Yes.
But acknowledging the problem doesn't help us solve it.
This is to say, Rust is an amazing labour of love project that seems rather stuck in time due to lack of investment/time/effort or all of the above, I am not sure, but it's moving slower than I would like, at solving the problems Rust developers face everyday.
And yes Rust compiler is slow (very slow is arguable, compared to modern C++ it isn't that bad, but compared to say Go without cgo, its horrid), Cargo is just bad, without proper hermetic builds and stuff, even when I setup sccache for our team and our cache hit rate remained below 20% and most of it was just C++ deps hitting the cache.
Just to be clear Zig builds are quite slow too, especially on windows where debug builds also use llvm.
TBH Zig debug builds on Linux also don't really feel that fast, C still compiles faster for me by a considerable margin.
Either way as someone doing Rust everyday for last 8+ years, 5+ in small/large teams, I have lots of complaints and I am sad, it has been over years of me complaining without nearly enough progress, they have a survey declare ambitions, and then well... things just don't move much.. not nearly as much as I would have expected.
Honestly given I have been a rust dev for over half a decade now, I should instead of commenting here probably be figuring out if I can contribute to Rust to help things along (faster?).
But most meetings and discussions happen at very EU/US centric times, and number of non US/European core contributors in Rust is also rather small(I don't know of one but I hope there are a few) so as someone not in those circles, I don't have the energy to figure out my way in, with my day job.
Tldr; Is Rust the language for the job here, likely. But the question should be why couldn't have been the language Bun was written from the very start. Why does Zig or C++ or C seem so much more productive.
Sorry for ranting about this but this felt a little relevant since you claimed people complaining, are likely people who have never worked with Rust.
The comment you're replying to wasn't arguing rust > GCed languages (e.g. C# or whatever game dev language you are thinking of). It was arguing rust > non-GC non-safe languages (e.g. zig).
I see that now, thanks. There's a lot to say here, especially with other approaches to memory management. My overall goal was to give them some context that wasn't their own.
> Beside that, for many problems, a garbage collector eliminates a large amount of defects (including the ones stated in the article)
Languages with garbage collection are generally considered "memory safe". GP was talking about choosing a language that requires manual memory management, but doesn't have something like rust's lifetimes to catch things like use-after-free.
For what it’s worth game devs often use C# or C++ engines which have even worse issues. Rust also has the early beginnings of hot reload which bevy adopted if I recall correctly [1]. I still think a higher level language is good for “business” logic to orchestrate how efficient low-level pieces connect, but Rust is holding its own even against those use cases IMHO.
[1] https://docs.rs/hot-lib-reloader/latest/hot_lib_reloader/
> For what it’s worth game devs often use C# or C++ engines which have even worse issues.
Such as? You can't be referring to hot reload alone because you can already do that in both C++ and C#.
> The rust compiler is very slow.
It was very slow. It's gotten a lot faster over time (over 2x faster). It's still not exactly fast, but it's definitely faster than C++. Although C++'s slow compile times are often complained about they were never really enough to stop most people using it, including for games.
> a garbage collector eliminates a large amount of defects (including the ones stated in the article) without any added friction
I'd be careful about that "without any added friction". Rust's lifetime/borrowing system tends to lead to less buggy code because it encourages structuring code in a less spaghetti way. GC does eliminate memory errors but you also lose that non-spaghetti code structure.
Because contrary to Rust, C and C++ have a culture of binary libraries.
You are seldom compiling the world from scratch.
Especially in the platforms dear to game devs.
> The best way to speed it up appears to be organizing a codebase in many crates.
A "crate" in Rust is the unit of compilation. In C, a file is the unit of compilation. Rust just lets you have a compilation unit that's composed of more than one file (without having to resort to C-style textual inclusion). But if you want, you can certainly have one-file-per-crate, just like you would in C. And what's nice about having many crates is that crates forbid circular dependencies, which trivially enables coarse-grained parallelism in the build system. So yes, organizing a large codebase into crates is the best way to achieve parallelism, but that isn't something to be deplored (and strictly controlling circular dependencies is useful for comprehending large codebases in general).
The forbidding of circular dependencies is exactly what makes it hard to achieve parallelism! It means you have to draw nice clean module boundaries and split your compilation units there. Clean boundaries sound nice, except… what if the module is getting large? Can you just take half the module, ctrl-x, ctrl-v into a new file, and get faster compilation times without having to do any massive refactors?
In C, usually yes.
In C++, sometimes yes. It depends on how template-heavy the code is, but if you have some discipline you can keep most logic out of headers and thus easily splittable.
In Rust, almost always no, because of circular dependencies. You can try to work around it by adding `dyn Trait` everywhere, but that requires a lot of code changes and comes at big ergonomic costs (and a small runtime cost).
Which is why in practice, Rust compilation units are almost always larger than C++ or C compilation units. Rust can sometimes be competitive with C++ on compilation speed anyway, thanks to a smarter build system and not having to re-parse headers a billion times, but usually it's slower.
> Can you just take half the module, ctrl-x, ctrl-v into a new file, and get faster compilation times without having to do any massive refactors?…In Rust, almost always no, because of circular dependencies
This feels like a strange, overly-specific complaint. It reads a bit like “When I write entangled code, it’s hard to untangle”. Like, yeah, the only thing that’ll save you from that is…not writing entangled code? I’m not of the opinion that the argument of “yeah but C lets me do whacky stuff” is a particularly strong line.
FWIW, letting a module grow, and then splitting modules up by cut-and-pasting stuff out along natural domain lines generally _is_ how I write Rust. Largely due to how easy it makes it to construct modules and submodules.
The industry accepted way of handling circular dependencies is to not have them and heavily lint against them in languages which permit them in compilation or runtime.
Hey thanks for teaching me a word today, and to be finicky myself, the convention seems to be to use a single n it. :)
The main reason to use C++, and Rust compiler also falls into it, is existing infrastructure, SDKs and industry standards.
I would love that Java and .NET would provide all layers like several managed languages in the 90's,
However it has taken a quarter century to get back features we already had in Modula-3, Mesa, Oberon and co.
> and you decide to drop to down to C++
Going from Rust to C++ seems a strange choice, since you get most of the same problems just without memory safety. Zig, Odin, C3 or even plain old C though? At least those languages have things to offer that neither Rust nor C++ provide (and if it's just compilation speed).
> I can understand when you need the absolute best performance and you decide to drop to down to C++
Rust is just as fast as C++.
It depends just how fast you need it. C++ is much easier to get to zero abstraction code.
In Rust you are constantly fighting the stdlib and other libraries, and you have to litter your hot code with unsafe blocks to get it to stop adding a branch to nearly every object access, be it for bounds checks or over/underflow checks.
C++ does a much better job at giving you a zero abstraction API, and you can always drop down to raw pointers if you want, without(!!!!) unsafe blocks and weird tricks. Of course it's unsafe in C++ but the friction to writing a branchless hot loop is muuuuch smaller.
When profiling and optimizing Rust code, I very often find myself poring over the generated code, making small changes, reading api docs, and trying again, much more than in C++. Lots of unsafe Rust APIs are not even nearly good enough, even with most checks turned off you will find branches that just branch to panic!(), which is, you guessed it, still more code and a branch than the code would suggest.
I get why people think that most systems languages are the same "speed", but they really are not if you are hitting limits of the hardware in your hot loops.
How is not having to mark your unsafe code as unsafe a good thing?
You couldn't have come up with something more incomprehensible.
If 99% of your code doesn't use unsafe, why contaminate 100% of your code base with footguns?
I agree with your point, but for completeness:
> How is not having to mark your unsafe code as unsafe a good thing?
The problem with unsafe code in Rust is that IIRC nobody actually figured out yet the "rules" of unsafe i.e. which invariants you can stretch and which can cause UB. My (not super up to date) understanding is that this is an active area of research and progress is being made and also that in practice there are many well understood usages.
In short unsafe rust is somewhat worse than C++ as the boundaries of UB are less well understood/defined
Is it though.
There are so many situations where something is guaranteed to be safe but there is no way to express that in the Rust typesystem, so the only thing you can do is to wrap everything in Arcs and Mutexes, which introduces allocations, pointerchasing and locks
Hard to imagine a scenario where you don’t need a mutex for correctness and yet somehow Rust forces you to do it?
Unless maybe you mean tokio’s work stealing executor, but you can just not use it.
yeap, unfortunately, only few can see this.
It depends a lot on the coding style. The sort of Rust code that's heavy on Rc, Arc, Box, RefCell etc... (e.g. the typical band-aids to work around borrow checker restrictions) will be slower than typical C++ code (it's also possible to kill performance in C++ of course, just use std::shared_ptr for everything). E.g. I'd wager that performant Rust code is trickier to write than performant C++ code because you'll have to design your entire Rust codebase around borrow checker restrictions, while C++ lets you 'cheat' without having to fall back to helper types that incur runtime overhead.
It's not though. It's fast enough for many applications but if you need to write a hypervisor then suddenly bounds checks and atomic pointers become significant. Not to mention that rust dramatically reduces your ability to control where memory is allocated.
I write in rust and c++, rust isn't as fast. Rust is easier to work with and, compared to the Java crap it's replacing at my work, it's a lot better but it's certainly not zero cost abstractions the way c++ can be, nor is it great for data oriented design because you're hoping the compiler will do the right thing, consistently.
> and human involvement
Isn't ironic for a project that successfully killed all past and future human involvement?
I'll bite. The first language I could "just write" in was C. I had internalised the language and its standard lib and didn't need the internet to work with it.
Rust is pushed by many as the replacement to C, because of the memory safety guarantees. I'm sympathetic. I worked with Haskell for a time, so I get it. But Rust seems quite complex. There are so many language features that there's memes about it. There's also the friction and learning curve.
So, for fun, I choose zig because, like C, I can hold most of the language in my head and "just write." I choose zig because it does a great deal to help me write correct and highly performant code. I can use arena allocators and defer and cure my code of many memory issues. Then there's the various language rules around pointers (optionals, slices, etc) that help me write correct code. There's the built in testing and the test allocator. I love that comptime and the build system are not special cases, but rather are just garden variety zig. I love the simplicity and elegance of it all.
I also choose zig because I prefer the liberty it affords me. I am responsible for each and every allocation. It appeals to my libertarian sensiblities.
> The first language I could "just write" in was C. I had internalised the language and its standard lib and didn't need the internet to work with it.
I bet $4.20 you didn’t write C. You wrote something C-like which the compiler didn’t reject because the C standard has a gigantic surface of ‘undefined behavior’ which means once your program does one thing out of spec it isn’t C anymore silently.
> There are so many language features that there's memes about it.
Like many memes, these are misleading. Rust is a solidly medium-sized language; smaller than Python, certainly, though with a perilously steeper learning curve than Python.
Rust-the-language may be medium-sized. Rust-the-stdlib though?
The Rust stdlib has a lot of essential low-level types needed for adding a 'semantic layer' on top of the language so that the language user can exactly 'express intent' (types that arguably should be language features instead). Just look at all those detailed methods needed to make RefCell work, and what does 'into_inner' or 'undo_leak' even mean?
https://doc.rust-lang.org/std/cell/struct.RefCell.html
E.g. what's a single concept in C (e.g. "the pointer") easily has a dozen specialized equivalents in Rust, just because Rust needs the additional information to do its memory safety magic correctly.
The entirety of Rust and its stdlib has a huge 'semantic surface' compared to most other languages (even C++), and I think this difference in the semantic surface size to other languages is exactly the one thing that either attracts or repels people to/from Rust ;)
People get attached to things they've been using for decades. Also most of the world is still written in c/c++ so any critical mass has quite a lot to go up against.
Rust isn't perfect but it solves a lot of the pitfalls of C++ (not just UB, package management, horrible cmake files, linker errors etc.)
Im constantly surprised by the disk size required by rust builds. It takes over 50G to compile zed IIRC.
My personal memory and concurrent-safe option is Swift. And I agree, choosing a non-memory safe language for a new project is close to irresponsible today…
I've observed that dumber models are able to vibecode in safe languages a lot easier since the compiler errors can self correct the models hallucinations, while they end up marking a task as complete in dynamic languages despite it not actually working.
If I'm vibe coding something I'm always just going to do it in Rust.
Agree 100%. Almost everything I have written with AI is in Go, and strong typing is really really nice (as is go vet and golangci-lint to keep the generated code in line).
I imagine writing plain js or python with it would be much much riskier.
rust is still a non starter in some niche embedded applications (way too big). i still write c and assembly constantly.
> way too big
https://github.com/tormol/tiny-rust-executable
This produces a 137 byte binary. Obviously AMD64 isn't used in embedded, but I've seen ARM ones that are in the ~256 range.
It's all in how you use it. Of course, if you don't care about binary sizes, they can get large, but that's very different than actually paying attention to what you're doing.
I tried to use Rust for a tiny microcontroller (GD32VF103, 128KB flash).
First of all, I was amazed by how much I could do with Rust (safe Rust, even), and how well it was interfacing with my handwritten RISC-V assembly. I will definitely use Rust again for the next such project.
But, every time my functions would get over a certain size, suddenly some optimizations stopped working, and Rust was trying to put the whole panic/fmt machinery into the thing, going above my linker's flash size limit. It was insanely frustrating, since there was no rhyme or reason to it. Simply adding another branch to a match made it do that. Or another if statement that was exactly the same as the 4 before it.
The 137 binary thing does not scale.
> niche embedded applications
How niche are we talking? Rust is deployed on a bunch of popular microcontrollers at this point
> I can understand when you need the absolute best performance and you decide to drop to down to C++
Could you help me understand with an example or two? My understanding is that well written Rust and C++ are often identical in performance thanks to relying on the same compiler backend (both clang and rustc use LLVM).
Even, possibly, the other way around in some cases. A seemingly identical program may (and it does occur) compile to a faster machine code in rust than in C++ due to extra markers (eg alignment) that rust compiler is able to provide to llvm.
> I can understand when you need the absolute best performance and you decide to drop to down to C++
What? Rust generally doesn't have worse performance to C++, so this argument makes no sense at all to me.
> and I also relate with just personal preference, but beyond those it seems a no brainer to me.
That's another argument altogether.
It's totally fine to have preferences and decide to go with them of course.
that you understand and think dropping down to C++ is what you need to do when you "need the best performance" is quite enough of a tell to invalidate the rest of your opinion here. if you "need the best performance", you need to ditch OOP and RAII, and you're probably reaching for C. Zig wants to be the better choice there. that's a perfectly reasonable niche for a language to exist in.
if you read the article carefully, jarred is pretty clear about how their specific requirements with Bun cause friction when bridging the manual memory management of Zig with a garbage collected JS runtime. at face value, that makes quite a lot of sense to me, and it's a pretty specific scenario that is not the full on condemnation of memory unsafe languages that your comment is.
It is widely accepted that you can get better performance with c++ far easier than C. Outside of custom rolling assembly , a large aspect of performance tuning is compile time optimization, which is extremely non trivial in C, while being supported in language with C++. All the things people associate with C performance can be done in C++, the converse is not true
the point of c++ when you need max perf is to be able to maintain the compile-time abstractions you need w/ templates instead of macros and undocumented optimizer behavior, not oop or raii
you're right that that is a weak argument against C++ in that use case (biased by my own dislike of the language); but it is also a niche that Zig fits into quite well. so it's weird for the OP to claim it's ok to drop down to C++ when needed while kind of suggesting they don't get why anyone would use Zig
If you are willing to hand code intrinsics it doesn't really matter what language you pick from a performance perspective. Rust consistently shows it has better performance than c++ in code that does not hand code intrinsics. If cpu(not gpu) based performance is all you care about there is no reason to pick anything but rust. Modern c++ devs have no trouble with the borrow checker either they are already doing all the things that keep it from complaining. The reasons someone might not pick rust involve integration with existing code, the complexity of the language, and the depth of it's dependency trees. The complexity argument certainly doesn't lean you towards c++ or probably anything with an llvm back end. The openbsd approach to c is probably as simple as you can get these days short of forth or something equally obscure. Dependency trees are deceptive. We all have deeper trees than we think we do, but the rust front end itself has well over 100 crates in its tree...
All that said, I use rust for everything.
To add more context around lifetime errors and TigerBeetle's particular style guide:
>Many projects opt to answer these kinds of questions through a style guide. TigerBeetle's TigerStyle is an example in Zig and Google's 31,000 word C++ style guide is another. The challenge with style guides is enforcement.
TigerStyle[1] is a bit more than just a style guide. The key rule for this discussion, uplifted straight from of NASA[2], is *static memory allocation*: all memory is allocated in the startup phase, and there's absolutely zero `alloc`s afterwrads . This plus crash only[3] design means that we never call `free`.
This rule is self-enforcing and compositional, in Zig. There's no global memory allocator, so the code after startup simply hasn't the API to allocate. You can't circumvent this by accident. Of course, if the programmer is byzantine, they can stuff allocator in the global, or just directly `mmap` and `unmap` pages of memory, but, at our scale, we don't have problems with that. This is a similar in kind (not degree) to Rust, where untrusted code generally can circumvent safety guarantees, even without literally spelling `unsafe`.
And, naturally, never `free`ing goes a long way towards solving many memory errors by construction. Empirically, they just haven't been a problem for TigerBeetle. It's hard to untangle contribution of static allocation in particular from everything else we are doing, but it would make sense for it to play a leading role.
(As a footnote, we aren't actually do static allocation to avoid memory errors, we use it as a linter to check that every quantity has a known _logical_ static limit, the main property we care about)
[1]: https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TI...
[2]: https://spinroot.com/gerard/pdf/P10.pdf
[3]: https://www.usenix.org/legacy/events/hotos03/tech/full_paper...
I think the important thing is this is much cheaper than hiring a software engineering team. They could have hired me for 200k and I could not do this in a year. I do not have the context, and I do not know Zig or Rust, perhaps I could pick it up in a month, but I would be extremely slow.
Forgetting all the predictions about singularity etc, at the very least AI as it is now, is going to make it very hard to justify hiring a SWE for 200k. I will say, at the very top for a software heavy company like Google or Anthropic, they will still hire excellent engineers to create new software that AI is not very good at.
But for companies where software is simply a cost center. Like Walmart, or Target, companies that were already outsourcing software development, or using cheap H1bs, now they have the alternative of AI which is much better than even hiring an average software engineer for 200k. This is a sea change in the job market, it’s going to have a pretty big effect as it is right now. US has around 1.6 Million software developers, this number is going to get cut drastically, the very top, say an L6 quality in FAANG will be fine, the average in a no name Bank, or the guy building the website for McDonalds is out, he needs to learn something else or he’ll end up without a job soon.
I would not have predicted this a year ago, now it seems clear that this will happen. Just shows how much of a sea change we have witnessed just like that.
"In economics, the Jevons paradox is said to occur when technological improvements that increase the efficiency of a resource's use lead to a rise, rather than a fall, in total consumption of that resource. Greater efficiency reduces the amount of the resource needed per application, lowering its effective cost; if demand is sufficiently price elastic, this induces demand, frequently resulting in a net increase of total resource consumption."
It is highly debatable if a 200k cost engineer that is suitable for the job wouldn’t bring in more value.
Also it is debatable they got any value at all from this. Anyone who wrote unsafe rust and also wrote zig would know that unsafe rust is much much more unsafe in comparison
It's only 4% unsafe and most of it is single-line pointers that came from C++
> At the time of writing, about 4% of Bun's Rust code sits inside an unsafe block (~13,000 unsafe keywords across ~27,000 lines / ~780,000 lines), and 78% of those blocks are a single line — a pointer that came from C++, or one call into a C library.
I don't know much about Rust but I imagine this is safer than 100% 'unsafe' code in Zig or C++.
That’s a lot of unsafe. I worked in a project with 50k lines of rust. 9 lines were unsafe. Turned out one of those was a hairy bug. Now it’s 8 lines.
4% of 100k is 4k. 4k lines of unsafe rust is more likely to be unmanageable compared to 4k lines of zig or c dependency on a 100k line rust codebase.
Not sure if they have 100k or a million lines of code
I'm not so pessimistic. There is an infinite amount of work that could be done. No one would have entertained the idea of rewriting a project in Rust before this. It hasn't replaced anyone's actual job and they still had to hire a high paid employee to pull it off.
I suspect rather than hire less people we will just produce more code changes.
But do the markets care about a Postgres in Rust? Probably not, or at least not right away. It is a long way towards commercial success.
> I suspect rather than hire less people we will just produce more code changes.
Why? Towards what end? Code changes are output, not outcome. It also needs to be connected to someone willing to pay you hard cash. That is the hard part, a race to the bottom, and the reason I also believe there will be downwards pressure on salaries and even employment.
It's funny, I see the opposite and I would only trust a senior engineer with conducting such a wide-reaching change. I would be more likely to hire a senior engineer who might now be able to effect such change.
Not only that. I think most of us, including the author wouldn't have thought this was actually feasible.
Not only is the time and dollar spent lower than a lot of people expected. We could now foresee a lot of these human interaction, mistakes, time and cost could be further reduced by a factor of 2, 5 or even 10+ in the not far future.
Also worth taking into account what is stated in the blog post is also acting as PR piece for Claude and LLM in general.
Ehh, I think this take needs a grain of salt.
There's a few significant facts here:
- They had an existing functional Zig implementation
- They had an existing test suite for the Zip implementation
- They had a separate JavaScript compliance test suite with ~ 1 million tests
- The person overseeing the rewrite was responsible for a huge portion of the existing codebase and was very familiar with the existing architecture and problems
I don't think that middle management at most companies is going to be starting from that same point when it comes to building or updating something. Generally, I don't think there are many projects out there that have such robust existing tests and specifications.
In this case, the engineering behind the tests and specifications need to also be considered part of the process, since without those you wouldn't be able to build a control loop in the same way.
Also I'm pretty sure Walmart directly hires software engineers and doesn't just outsource everything - https://careers.walmart.com/us/en/results?searchQuery=softwa...
I think this problem is especially perfect for an LLM though. Its effectively translating with a great test harness.
As for your other arguments, I’m not certain we won’t just Jevon's Paradox into more work.
Getting tired of these comments trying to hype AI. All of us use AI, and if we don't, we have a reason. Chill.
> I think the important thing is this is much cheaper than hiring a software engineering team. They could have hired me for 200k and I could not do this in a year.
Sure, if you're wasting money in silicon valley. They could have hired in Europe and got three people for $300k, which is only double what they spent.
I think the time is the really significant factor, not the money. I bet if they had the option of paying $300k to have it done by humans rather than AI, but magically in a week instead of a year, they would have gone for that instead. $300k is nothing to Anthropic.
If you already employed the engineers the extra cost would have been $0.
Opportunity cost is not a real cost. No money leaves your bank account. It is a decision making tool, and treating it as an actual financial cost is a misuse of the idea.
It’s literally the price of lost opportunities. It’s not understood to be a financial cost. It’s exactly what it says on the tin. Lost opportunities may not be a financial cost, but they’re certainly a cost.
> They could have hired me for 200k and I could not do this in a year. I do not have the context, and I do not know Zig or Rust, perhaps I could pick it up in a month, but I would be extremely slow.
All that really proves is that you’d be an astoundingly poor choice to hire. If you’re spending $200k on someone that doesn’t know at least two out of three (context, Rust, or Zig), you’re just burning money.
That’s not to say that experienced engineers familiar with the stack would or wouldn’t be able to do it in a year, but they’d certainly have a better shot at it.
It’s also not that this project sprung into thin air from a quick prompt and LLM magic… it was driven by a dedicated, highly talented, subject matter expert with extensive SWE background and extensive support from the leading experts in the world. You’ll continue to need someone to steer the ship, even in the Wal-Marts and Targets. An LLM is only ever as good as the input it’s given.
Without commenting on Bun itself as a project, or the nature of the rewrite, it can't be good for Zig that a naive rewrite away from it fixed memory leaks, improved stability, shrunk binary size by 20%, and improved performance by 5%.
I don't think it's care to categorize this as "a naive rewrite away from [Zig]" - Jarred has been immersed in this project for five years, got to benefit from everything he learned along the way and spent $165,000 of tokens on the most advanced coding LLM anyone has access to.
I expect if he'd spent $165,000 running Fable against the Zig version he could have got a 5% performance improvement, too.
I can confirm a naive rewrite won't make things faster. I've been working on rewriting Postgres in Rust. I rewrote things function by function similar to how Jarred did. Even though the new Rust code mapped closely with the previous C code, it was 8x slower. This was due to myriad of reasons. For example naively converting a C union into a Rust enum can be slower because Rust stores a tag with the enum, while C unions do not.
I've been working on a new rewrite that's focused on beating Postgres on performance. As of this morning I got to 100% of the tests passing and have meaningful performance gains over Postgres.
I find it curious that people who take other's people product and rewrite in their favorite programming language still name their own creation the name of the original one.
Like, you have now created your own new database engine that happens to be compatible with Postgres. Wouldn't you take an absolute pride in giving it your own name? Why call it "Postgres rewrite in <programming language>"?
Would love to follow your journey!
If you want to follow along, I've been writing about it on my blog (https://malisper.me/) an you can follow the github repo here: https://github.com/malisper/pgrust
> and spent $165,000 of tokens on the most advanced coding LLM anyone has access to.
After having used 2 full weeks of 20x Max plan tokens on Fable over the weekend (coding all day Saturday and Sunday on a non-trivial project, tasks across full stack, mix of adding features, reviewing code, and fixing bugs), I’m confident if he’d spent $165,000 in Opus tokens the port would have gone more or less just as well (and probably for less than $165,000). Especially so with the system they set up with all the custom workflows, adversarial reviews, extensive test coverage, etc.
But I get your point is probably more about Jarred’s experience level and the high cost than the specific model used other than it being SOTA. I’m just being pedantic and feeling a bit disappointed with Fable’s real world performance after all the hype.
> I expect if he'd spent $165,000 running Fable against the Zig version he could have got a 5% performance improvement, too.
Totally agree and in fact I’m sure it could be done with significantly less cost even if they stuck with Fable instead of Opus which I’m sure could also do it.
Fable is kind of fantastic on the difficult tasks. if it's something eithe rmodel can do then you can't see the difference. Fable also makes much less mistakes. It's a more relentless, proactive problem solver.
I’ve been noticing that it will test hypotheses for evidence frequently. I really like that. With Opus I have to instruct it with a skill to build prototypes, but Fable will do it and do it really well by default. Really nice detail. I’m guessing it’s part of the system prompt, but the higher capability paired with this experimentation lean makes it far better at planning and verifying.
Oh, I have no doubt that they could have extracted those gains from Zig! My point is more that, from a relatively naive line-to-line port, they were able to claim these benefits without much effort.
It's not great for Zig if you have to put in more work to end up at the same place efficiency-wise, especially for a language marketed at people who like to get the most out of their metal.
That's not what the article says though. The size reduction was from extra linker flag for deduping code, and the speed gains from LTO.
They could have done the same in Zig, even though it probably shows cargo is better at this than build.zig.
I hope Zig won't do a hostile reply to this blog post. But some thoughts on Zig's future where a lot of these problems could be fixed or migrated by better tooling and compiler checking.
But a lot of people have been saying this for sometime, Rust and LLM is a great match. A lot of friction of the language were smoothed out by LLM assisted programming.
I would guess that people looking to use Zig understand that those are project concerns and not language concerns.
The stability gains are a direct language concern as mentioned throughout the article.
True, but rewrites often allow for this sort of benefit in themselves. It's possible rewriting it in zig would have yielded some of the same improvements.
I pay attention when someone makes a hard decision based on a hard-learned lesson. It's like, most who choose to use an ORM just heard of it or want to avoid learning SQL, everyone who removes an ORM learned firsthand horrors.
Funny you mention ORMs, I'm building a project with bun, and just using raw bun sqlite until I feel the app gets too complicated and I need it. AIs are really damn good at SQL, I can just trust them with it, and it keeps the project much lighter. A few years ago this would just sound stupid, but here we are.
The result of this will be that you end up at the highest level of abstraction.
Let me save you time and tell you that C# and it's ecosystem is where you'll be happy.
While it's easy to look at it that way on the surface, from reading the blog post, it sounds like a big part of it may just be the nature of Bun as a project.
Wouldn't the same improvements have been made in zig if they instructed the agents to improve instead of rewrite?
But how would you verify that the agents have written memory safe code? Rust's borrowchecker is a lot faster and actually verifiably safe compared to asking an LLM to fix the safety issues that the Zig version had.
Maybe they'd get the same numeric improvements and bug fixes today (or maybe not, or maybe they'd get even more since the LLM isn't spending time rewriting correct code).
But they wouldn't get a change to the structural issues that created the issues in the first place. They'd end up "ke[eping] fixing these kinds of bugs one-off in perpetuity".
Unfortunately (and I say this because I hate this whole rust rewrite) no. There is no fixing a third-party garbage collector on top of the non-memory-managed language. Jarred explains in a post what would that Zig look like.
The same concern applies to every GC language, so it's not necessarily bad for Zig. Bun can have been grown too large for Zig to be effective, while moderately sized projects may still greatly benefit from Zig.
I thought Zig was supposed to be a C replacement (as in, it doesn't actually provide full safety in the way that Rust or a GC language would)?
Oh, yeah that might be confusing. I meant "you can say the same thing for GC language if that's true, which isn't necessarily true, so that must be false".
More precisely speaking: GC languages are said to delay memory problems far beyond the horizon, which is often unreachable throughout the project's history. Zig can be a similar case.
Ah, I understand now. That said, I still think there's a pretty strong argument that this is a lot worse for Zig than a GC language, because they also give you safety for that overhead (and potentially ergonomics). When a language is trying to operate in the same niche as C with what seems to be an overt attempt to be less cumbersome than Rust even if it makes it less safe, it's a bit concerning to see that even without the safety it seems to have more overhead rather than less. Put another way: it sounds like it might as well just add a GC if it's not going to be competitive on performance.
zig has been developing too slowly. it still cannot reach a stable 1.0 (to the point that even vsc autocomplete gets its Hello World wrong), and then it ran headfirst into AI.
Yeah but they turned it into something unreadable. Call it a skill issue if you wish.
I just haven’t found another language that just makes sense. Zig doesn’t hide anything from you
>they turned it into something unreadable
Did you compare the code before/after? It's a mechanical line-by-line port, and most of the code is identical to the old version, just with Rust syntax. They have an example in the blog post.
But how can it be a mechanical rewrite if the tool used isn't deterministic?
It converges to "almost deterministic" on highly predictable outputs (i.e. code) with the right sampling params (say, you only sample the most probable token without randomness/high temperature) and with self-correction loops
The article explicitly mentions the maintainability as a foremost concern.
People say a lot of things, especially when they have a vested interest in a positive outcome. Bun has been fully vibe coded into another language. There’s no way in hell it’s maintainable. Go read any analysis of the Claude Code leak for proof.
Claude Code is entirely vibe-coded for a long time. Bun isn't. You go read and compare the actual Bun code; it reads reasonably well [1].
[1] For example, as a random sample, https://github.com/oven-sh/bun/blob/bun-v1.3.14/src/css/medi... -> https://github.com/oven-sh/bun/blob/4924862cffbf671792d47c92...
Sure, reasonably well at first glance, but to quote the article:
> I rewrote Bun in Rust using about 50 dynamic workflows in Claude Code run continuously over the course of 11 days.
> Excluding comments, Bun is 535,496 lines of Zig.
> How do you review a PR with +1 million lines added? How do you start to build the confidence needed to responsibly merge large quantities of LLM-authored code? A language-independent test suite with a million assertions, adversarial code review and when something does go wrong, fixing the process that generates the code instead of hand-fixing the code.
That’s vibe coding. This blog post is an ad for Claude, nothing more.
You're entitled to call things as you wish, of course, but your definition of "vibe-coding" differs quite a bit from mine.
500k lines in 11 days? With 8-hour working days that's 100 lines per minute. There's no way you're comprehensively reviewing code that quickly.
The code was generated by a LLM, and the output wasn't even read by its user. That's definitely vibe coding.
It's a direct translation without changing the overall code structure or data structures. I do think this process deserves a distinct name from blind whole-of-project vibe coding.
Translation does seem to be a strength of LLMs, and as they said in the post, the code at the function-level all still feels familiar to the team. They've also already moved users to the codebase without anyone noticing; that's a better result than typical vibe coding.
Doesn't look like vibecoding to me. It does look like a Claude ad, but they do have a vested interest in not screwing up Bun now that they own it.
What would be the consequence to them if they did screw it up? Screwing up the maintainability of a project, especially a big one, doesn't necessarily have immediate consequences. The fallout could be delayed by a year or more. Also, they have effectively limitless tokens to burn on keeping everything looking OK, and a vested interest in doing so.
I'm not trying to spin up some kind of conspiracy theory here, but I'm not sure to what extent Anthropic does have any vested interest in this project (in fiscal terms at least) because the reputational fallout could be significantly delayed and might just not be big enough to matter.
Claude Code is the main reason their revenue (ARR) grew from $9bn to ~$47bn in the first half of this year.
That's a very big reason not to screw this up.