403 comments

[ 2.3 ms ] story [ 102 ms ] thread
Adding bespoke animations via Claude Code to the blog post is definitely thematic. It's unclear if they're useful data visualizations as they take a bit of time to parse, but they're neat.
One thing that I found interesting is that most of the discourse surrounding the topic happened with the assumption that the rewrite was happening with an Opus-like model, and not with Fable. Those assumptions, at least partially, were used as arguments against the fact that the rewrite was feasible and/or a good idea.

Clearly the model itself doesn't completely change the narrative, but at least as a note to myself, I would like to be more careful with assuming the capabilities of the models used internally by Anthropic and affiliated orgs.

I thought the same thing. Looking back, a possible signal for next time is when we see an Anthropic owned company disabling the Claude Co-Authored-By trailer.

Normally they'd be taking every chance to promote Claude usage unless it was something (Fable) that we weren't supposed to know about back in May. https://github.com/oven-sh/bun/pull/30412/commits

Silly assumption, Mythos was available at the time. Benefit of the doubt should've gone to Jarred.
Claude, rewrite Claude Code from TypeScript to Rust.

Make absolutely zero mistakes.

1 Developer with a 200k budget for tools.
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 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.
Judging from comments on this article: no.
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

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.
> There’s no way in hell it’s maintainable

This is not an assertion you are qualified to make

> Go read any analysis of the Claude Code leak for proof

You seem to be implying that Claude code is unmaintainable. Yet they appear to be maintaining it just fine. Did I misunderstand your implication?

> There’s no way in hell it’s maintainable.

They rewrote the entire thing with extensive LLM use.

It is abundantly clear that their idea of maintainable and yours probably don't match up.

It's apparently out there, shipped in the real world, with people saying it's good. I think it's a pretty clear win for them.

> There’s no way in hell it’s maintainable

There are different definitions of "maintainable". It seems the prevailing culture at Anthropic is to not touch code manually anymore. So for them "maintainable" means the LLM can fix it.

>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
I find Rust more readable than zig
you're not alone.
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.
(comment deleted)
From a PL Theory perspective, Zig is vibe-coded.

Not sure why people use it.

Pretty much everything except Haskell and the like can be considered as such.

That's because closely following PL theory isn't always the right goal for a language. Ergonomics and pragmatism are far more important.

I wouldn't disaree on the ergonomics: a powerful but unusable tool is... useless!

Though ignoring all the PL lessons for the sake of "pragmatism" is just plain ignorance.

Rust has a quite solid theory backing. Zig has nothing interesting really: it's "vibe coded" by someone who was doing game dev or something like that.

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 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)?
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.
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 does it cause they heard of it, everyone who removes an ORM learned firsthand horrors.
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.

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.
That's what I always did pre LLM, it was fine
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 hope that you're going to call it PostGrust.
Then you'll have postgrest on postgrust
Na, PostPostgres would be much cooler.
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>"?

Maybe not everyone is utterly obsessed with vanity and its delusion?
Then why use someone else's established brand for your toy project?
If this is still speaking about the Postgres rewrite in Rust, then naming it something like pgrust[1] makes sense for ease of discovery for anyone aware of these technologies.

[1] https://github.com/malisper/pgrust I guess

If they did the opposite and called it Mygres or whatever people would give them shit for that too.
> 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.
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.
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.
The scary thing is the zig project prohibits LLM contributions - the world is going to move faster than them.
I would be pissed if my programming language changed as quickly as Claude code does. Languages need to move slowly and carefully, and zig is on the faster end of language development regardless.
I would be mad if the syntax was constantly changing but I want the internal implementation to be moving as fast as possible while retaining success. I think that rate is higher than what humans alone can do.
That's a monkey's paw desire because nowhere is Hyrum's law more true than programming languages.
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.

Zig and Rust solve different problems, Bun got burned by its indiscipline, and Zig’s response was sadly to flood HN with “how to use Zig” articles
I don't want to say I knew it but it did happen. Slightly disappointed.
On the other side of the scale, this codebase started in Zig from 5 years ago while the Zig of today is still very much pre-1.0 - still in the middle of things like finishing up moving to a self hosted compiler. Things like binary size, performance, or some of the oddities around drift in the language (like the custom macros vs now built-in language features) in this rewrite are not really as bad as they'd seem if this was a port from a more complete language.

That said, I think the parts around wanting to properly have memory safety guarantees rather than try hard & patch as issues are found is a more serious concern for Zig as those speak more to the design goals than the current implementation. "better safety than C while maintaining C compatibility" may not be a very compelling reason to chose Zig if other languages are able to do that portion better anyways, even ones without a GC.

“better safety than Zig while losing compatibility with C” doesn’t seem as compelling a story to me.
No, you don't get it. Zig is a language about having _fun_. Not memory safety and all that crap. That's why unused variables are hardcoded as errors!
I hope this isn't the takeaway!

Zig was the right tool to start, Rust is the right tool to finish.

Making something possible and refining something until it is high security and reliability are different problems. Zig is great, but for a JS runtime, I just don't think that's the best long-term fit.

> Claude Code v2.1.181 (released June 17th) and later use the Rust port of Bun.

It seems the reports of Bun's death have been greatly exaggerated.

This slop rewrite introduced new vulnerabilities and regressions.
Where is the cost breakdown? I feel like this would be the easiest number to determine and write in this post. It's hard to believe that there have been no problems/downsides since the port.
This blog post further undermines my trust in Jarred.

He makes it sound like Claude did a fantastic Rust rewrite, and "the work continues."

But when the Rust port merged to main, the state of the code was very, very bad. There were 13,000 instances of `unsafe`, no Miri tests at all, and, sure enough, it exposed UB in safe Rust. https://github.com/oven-sh/bun/issues/30719

Observers could see this coming from a mile away, objected strongly to using AI to RIIR before the code merged. Rather than incorporate feedback and get the code ready for production, Jarred gaslit us all, right here on HN. https://news.ycombinator.com/item?id=48019226

Just 9 days before he merged the Rust rewrite to the main branch, Jarred wrote:

> This whole thread is an overreaction. 302 comments about code that does not work. We haven’t committed to rewriting. There’s a very high chance all this code gets thrown out completely.

It's plausible that Bun's Rust rewrite is now in much better shape than it was in May. But a blog post like this would have been a place to apologize, to accept that it was a very bumpy rollout, to acknowledge that public messaging was extremely poor, and to earn back our trust.

As it stands, I guess I'll have to run my own tests to try to evaluate whether Bun 1.4 is ready for prime time, because I just can't trust Jarred to give us a straight answer.

> But when the Rust port merged to main, the state of the code was very, very bad. There were 13,000 instances of `unsafe`, no Miri tests at all, and, sure enough, it exposed UB in safe Rust.

I mean yeah, that's what this whole post is about. It's about the process of going from that original state to something that's now shipping in production.

That's the power of a strong test suite. LLMs excel when you have verifiable rewards. I imagine we'll get a lot more rewritten in rust projects in the future. Rust is also an ideal target for such rewrites as it offers a lot of verification (via its type system) and is low overhead with zero-gc. There's less and less reason to use GC'd languages in the agentic coding era.

I think Rust is a locally optimal target for LLM coding, we might see a better language in the future, but I think Rust will dominate for quite some time.

>Combined with the Rust rewrite, ICU changes, and identical code folding, Bun's binary size shrinks by ~20% on Linux & Windows.

People who are surprised by this probably has not seen what Zig code actually looks like. Zig's explicitness and lack of abstraction have a real cost that it is basically one of the most verbose programming languages I've ever seen, it's somehow even more verbose than Go. Basic features of modern languages like pattern matching and generics, and as you can see, having to manually clean up everything means that if you forget once, it's a memory leak. Having SOME abstraction is actually good if it prevents you from making mistakes.

Ironically, Zig is a programming language that's probably best written by LLMs, since they can actually tolerate the verbosity.

Naive was 4-9% on the initial pass.

Also note that the larger percentages were against already smaller binaries. That smells like there was a single large constant number that got saved somewhere rather than general improvements.

> After that initial shrinkage, the team explored more opportunities for binary size reduction using linker optimizations like Identical Code Folding, removing unused data from ICU, and lazily decompressing small parts of libicu with a zstd dictionary on-demand.

I'd be VERY interested in seeing what the individual effects of those parts were.

Abstraction doesn't necessarily lead to a smaller binary. Much of the bloat in modern software is indeed due to (bad) abstractions.
Zig is actually verbose in some aspects, but not overall. For example, its `try error-union` syntax eliminates a lot of boilerplate code.

The main reason why Zig is verbose in some aspects is the main goal of Zig is program performance. It is a worthy tradeoff.

That goal doesn’t imply verbosity is necessary- just a style thing which is contrary to its goal of being a better C, given verbosity is the opposite of most C.
Performance alone doesn't imply verbosity, but combining it with other goals—such as increased security and more power std APIs—does.
The twenty percent quoted is referring to the size of the compiled artifact (one assumes ELF or Mach-O).

Whether or not a language is verbose or obscure is very much about your coordinate system. Not unlike safety.

I think C is a reasonable zero for both things.

Zig is more succinct and safer than C while still being comparably ergonomic. Rust is (mostly) safer and more succinct than Zig while being dramatically less ergonomic (take it up with Wadler memory chads, no one likes affine types).

I like lean4, which is dramatically safer, more succinct, and more ergonomic than Rust.

But I can see why some would say it's a bit too succinct.

> Rust is (mostly) safer and more succinct than Zig while being dramatically less ergonomic

This is just your opinion.

Well, it's my opinion. But it's also the opinion of the broader functional programming community from 1993 to the present day. This notably includes the quite serious Haskellers who designed Rust for the highly specific and demanding requirements of the Servo rendering engine in ~2010. Being as my two parents in web browser layout optimizations were both filed in 2009 I took considerable interest.

It wasn't until 2014 that Orchard formalized the coeffect discharge calculus via indexed monad that makes a binary ownership semantic irretrievably sunsetted as a degenerate case.

It's my opinion. I'm not concerned about how informed that opinion is.

[delayed]
Inspired by this project I ported most of Valkey to Rust here valdr.dev .

The coolest outcome was being able to run a redis comparible store on an a cloudflare durable object so you do I.e. rate limiting for free with little infra.

So I kept hearing that the author did this purely because Anthropic wanted a PR story, but reading this entire very well written post, with meticulous detail, what say you now? I never thought it made any sense for him to do this just because Anthropic asked him to. Sometimes you find yourself fighting the stack you're currently using, and another stack (or programming language) looks like it would alleviate a lot. LLM was just another tool in his toolbelt. I had already ported projects that were old and abandoned before using Claude Code, so I knew it was possible.
So much of the discourse around this on HN is nonsensical, and I fully agree with you. It's patently absurd that Anthropic would demand him to rewrite Bun into Rust; it's equally absurd that they would demand any sort of stunt at all when Anthropic already pulled off the biggest stunt with Bun: running Claude Code on it. And why on earth would you cannibalize the runtime of your golden goose?
Every time I've rewritten a major project I've made it smaller and faster while fixing all the major bugs and most of the minor ones. My current team has had similar experiences. I'd be curious to see what a Zig -> Zig rewrite of the same magnitude would have done for quality.
Should we brace for another front page Zig donation announcement? A fast follow with a “Why Zig?” penance piece, replete with anecdotes about how it is the only true way to express oneself?
I still think that generating a Zig-Rust transpiler would be a better approach, given all the LLM quirks, including the ability to just /goal the model with binary-identical LLVM bytecode.

However, an open-sourced tool like that would've greatly harmed the Zig ecosystem and community.

Go famously used machine translation to remove dependency from C. It's a nice way to retain structural familiarity with the target language. I imagine they could've saved a large portion of that $165,000 using this route. Hard to say for certain, though. You wouldn't want to scope that transpiler at "being able to transpile all programs generally," and so scoping the project does become a serious task.
> Compiler errors are a better feedback loop than a style guide

So essentially this whole re-write was about making Bun LLM compatible.

> to exhaustively come up with reasons why the changes create bugs or do not work

My biggest issue currently, is I can't seem to get a code review that's about the simplicity of the code, and no /simplify ain't it. Removing certain bugs and generally working seems to be doing alright, especially if it's following either an example code (like in the Bun rewrite case) or a well defined "spec" of how to proceed.

They didn't mention the cost of this. Assuming mythos was somewhat involved I'd extrapolate this as: 128 x20 max accounts needed which comes at $25.6k or over 75k in api costs. For 75k you can hire a team of engineers that would produce a better result with sematic conversion and other tricks used in porting from language A to language B at the cost of maybe taking 1 month instead of 10 days.

I will be a lot more excited when this is possible with <10k of api costs.

I don't think the realistic alternative here was “hire a team for a month and get a better semantic conversion”

For a rewrite of this size, the expensive part is deep understanding of the underlying system in order to preserve behavior while keeping performance, and above all that not freezing product work while doing it. Adding more engineers would just end up in managerial burden and review bottlenecks, to say the least.

So even assuming the API cost estimate is high, I don't buy the “just hire engineers for a month” take. A team unfamiliar with the codebase would probably spend a large chunk of that month just building context and deciding how not to break everything. A team familiar with the codebase is even more valuable doing product work, bug fixes, and review of the existing codebase.

So, in short, I do agree with the simple fact that this is still too expensive for most projects, but not with the idea that “a small team would trivially do better in a month”.

I've always felt [0] the people who created Bun had, as their first and foremost goal, a desire to use Zig--and that's great, I like Zig, I like when people build things their own way.

However, I've been skeptical of using Bun, because I want a project whose first and foremost goal is to build good tools that achieve the objectives of the project.

It reminds me of asking game developers: Do you want to build a game, or do you want to build a game engine? Building a game engine is fine, but if you're goal is to make a game, then building an engine is a poor way of achieving your goals.

Likewise, I've wondered if the creators of Bun wanted to build better JavaScript tools, or if they wanted to use Zig.

[0]: https://news.ycombinator.com/item?id=35970044

So does that mean the rewrite made you less skeptical?
I mean, surely the main motivation for "use an LLM to rewrite a huge project in a new language" was excitement about the shiny new tech that made it possible.
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.

> 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 that 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.

I addressed some of these points in my reply to a sibling comment:

https://news.ycombinator.com/item?id=48856158

I may have been a little overly specific, since there are other issues besides cycles that also block splitting crates apart, but from what I’ve seen it’s very common for modules within a crate to have cyclic dependencies and therefore not be easily factorable into separate crates.

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.
You’re thinking at the wrong scale. Rust allows circular dependencies just fine, within modules in a crate. And it’s extremely common for modules within a crate to have at least some circular dependencies - type X has some method (trait impl of inherent impl) that mentions type Y, and type Y has some method that mentions type X. In fact, I would be surprised if you could name me a single medium-size-or-larger popular crate that doesn’t have at least one cyclic reference between modules! Though, sometimes those cycles are not essential and could be avoided by splitting up modules. But sometimes they are. Either way, in C or C++ those modules would probably be their own compilation units.

That said, you also run into related parallelism blockers without cycles. For example, the orphan rules force most trait impls for a type to be in the same crate as the type definition. Also, a module which has no source-level cycles will often have cycles after monomorphization. In this case, Rust doesn’t prevent you from splitting the code into crates like it does with source-level cycles, but you do lose most of the actual codegen parallelization unless you can switch from generics to trait objects.

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.

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?
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.

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.

> In general I'm not a big fan of unit test on simple websites, they do not give any real value compared to effort

And then your site gets more traction, features are added, things are refactored.

And now you're looking at what used to be a simple site, still with no tests.

It's a habit, that pays off long term. You don't do it for yourself, you do it for who changes the code next. Might be you, or not. Even when you do it yourself, you can't hold all the requirements in you brain, you write those up in tests

Mostly, because a lot of game engines are ancient relics, tracing their lineage all the way back to Quake 1.

The development practices are not exactly up to date, and game development is in no hurry to change. It doesn't help that software development wages there are not at all competitive - game development selects for passion, not skill. People who want to build robust modern codebases and people who want to build AAA games are different people. So there aren't many game devs who want to push for better test coverage.

But it's also because game engines are dealing with many, many things that are hard to test for.

You know how messy it is to test a website for "does this layout look right" or "can you navigate from A to B"? Now multiply that by complex 3D geometry. A lot of what game engines do is dealing with complex 3D geometry, where the primary verification is "does it look right" and "does this interaction feel right". Which is why game development traditionally has wide human QA, and slim unit testing.

Only now do we have software that can sort of, semi-reliably, automate testing for "does it look right".

I agree - maybe some modern game engines have unit tests for stuff like their physics engine and their "standard library" code (optimised data structures, maths utilities, string utilities etc) but as others have said, testing sound and vision is hard, and something that hasn't been mentioned is all the different flags in a game engine - testing even a sensible subset of all the different sound and rendering variables would be a huge undertaking.
> 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/

Not very popular, but it's nice to work with!

Even the physics engine they use is in C#: https://github.com/bepu/bepuphysics2

> It’s up there with Stride

Edit: I mean that it's up there with Flax: https://flaxengine.com/ whoops

Stride, Flax and jMonkeyEngine are all pretty cool, not just Godot and O3DE!

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.
Several C++ parts of Unity have been slowly migrated to HPC# though.
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#.

Well for c++ memory safety and sharp abstractions and even worse compile times than Rust. I’m not aware of hot reload really being done in c++ at any scale but I’m not a game dev so I’m open to learning.

C# AFAIK holds a minor place in gamedev and also has slow compile times maybe? I assume it has better support for hot reload times. But generally the performance profile isn’t there for the most demanding games even if the DX is.

It's not specific to game dev but Visual Studio has hot reload for C++ that you should be able to make use of.

C# compile times are fast. Performance is a lot better than you probably think, especially with modern .NET (not what Unity uses).

Visual Studio limitations around hot reload are quite unrealistic for any serious codebase and only work on Windows with Visual Studio when you started it under a debugger.

Rust’s hot reload is cross platform if I recall correctly and is always available until you disable it from the build (eg debug on, release off). It also has a better story for working around the limitations that Visual Studio just throws up on.

C++ hot reload is not a common experience in the ecosystem.

> only work on Windows with Visual Studio

Really shouldn't be a dealbreaker when 95% of your users will be using Windows, so your most tested platform should be Windows.

> when you started it under a debugger

Hot reload isn't a replacement for scripting IMO. It will never be as good. Even hot reload in Rust would have more limitations than an actual scripting language.

Sure, that doesn't take away from the experience of Rust being better than C++ even if you probably still want a scripting language too.

In total Microsoft only holds ~12% of the total video game market share across PC and console in terms of owning the platform (i.e. Xbox + Windows). I think you're overestimating how many game developers get to use reverse debugging for gaming. In practice given the limitations for Visual Studio's implementation, I highly suspect that number is very rarely used anyway.

It is a share big enough that Valve cannot have games for the SteamDeck without Proton.
Yes, it is, most game studios use Live++, a commercial product which whole goal is to enable live reload in game engines.

Likewise CERN's ROOT is quite famous, nowadays superseded by CINT, and integrated in Jupiter netbooks via Xeus.

> 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.

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.

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.

> tsc isn't fast but it's fast enough to get the work done, the annoyance is there but it's objectively minimal.

For our small codebases, maybe. The tsc-in-Go announcement had VS Code compilation go from >120 seconds to ten.

"Compiling" is vague here; for TS I think you need to distinguish bundling from type-checking.

If you're talking about bundling the entire app, 120 seconds down to 10 seconds is a great saving, but other bundlers can do it much faster already. Most people don't bother using TSC to bundle their code. I can understand why Microsoft might insist on using it, but it's not typical.

For type-checking the entire app, I would see that as akin to running all the unit tests. 120 -> 10 seconds is excellent, but not something that should be a constant bottleneck in your development workflow.

I can definitely see that 10x improvement being crucial on large teams (and/or LLM swarms) where the speed of the CI queue becomes a bottleneck.

Exactly: tsc was “slow enough to be painful” in the context of the 2.5Mloc codebase of VScode.

But it's not too slow for most people.

Likewise, Rust may be slow enough to be painful for some big projects that need to often rebuild from-scratch in release mode, but that niche is definitely much smaller than the size of the “rust compiles too slowly” on HN.

I gave Rust classes in university a few years back, and literally none of my students complained about slow build times. At this point it's much more of an internet meme than an actual pain point for most devs.

Small apps in college are much different than huge apps in the real world
Speaking as someone who has also given courses at university teaching a programming language (Swift,) the students also do not know how fast computers are and that when their brand new super-computer lags and hitches for full seconds while coding it's pretty much "working as expected" to them. I haven't written Rust in a few years, but I remember it being remarkably similar to Swift both in API design ergonomics and compiler quality. I am open to this having changed, and I can appreciate @stymaar's frustration if it has done so drastically.
Most people complaining about Rust being slow have never worked on anything close to a production app written in Rust.

By the way, for most apps, rhe difference from an app we'd write in class is not as nearly as big as you'd expect: most of the code lies within dependencies anyway, and you need roughly the same amount of them in both cases.

Of course there are exceptions, apps that are tens of millions of LoCs exist, but it's not the majority.

(And they tend to be naturally split in multiple crates, which is the default workaround if a rust project takes too much time to compile).

Compiling my C code with gcc happens in a single eye blink. Changing the format to .cpp and compiling with g++ takes 5 eye blinks. I've never used rust and I can't imagine blinking more than 6 times while waiting for my code to compile.
And you wouldn't need to, because the Rust compiler is "slow" relative to compilers like Go. Relative to Clang and g++, the Rust compiler is fast.
Most people use esbuild or swc or oxc instead of the typescript compiler directly specifically because of how slow tsc is.

In fact tsc was slow enough that it was rewritten into a different language for version 7, with the performance of the compiled output as the primary motivation.

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.
it is insanely slow. I regularly need to wait for minutes just for the final crate to compile when compiling some tui program from scratch
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 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.

> You are seldom compiling the world from scratch.

True in Rust too though - you're normally doing incremental compiles. And even though you're compiling the world, it's still on par with C++. For example I just tried compiling a hello world Bevy project, which has 462 crate dependencies - pretty big. It took 2m20. Totally reasonable to build an entire game engine and all it's dependencies.

I wish they had reported the compile time of Bun before/after the Rust port - that would have been very interesting.

See, but no game studio bothers to compile Unreal from scratch, at least not unless they are forking it for their own purposes.

Also incremental linking on Rust, or hot code reloading is still not something that works out of the box.

How beefy is that machine to achieve 2m20? I started using C++ on MS-DOS.

Especially valuable in current times.

> How beefy is that machine to achieve 2m20?

Ryzen 9 3950X (16 core). I think it was top of the line 5 or 6 years ago but it only cost me about £300 second hand for the whole PC (with 128 GB RAM - before the RAMpocalypse!) Definitely not a crazy machine.

> I started using C++ on MS-DOS, on a 20 MHz 386SX PC with 2MB RAM and 20 MB HDD

Yeah, I mean early C++ was quite a lot simpler than modern C++23! Of course it's going to compile way faster. You're not compiling UE 5 on that machine! Compilers didn't have so many slow optimisations back then either.

Yes, but no one needs to use C++23 to the full extent to stress test the compiler in -O3, or go crazy with compile time execution.

While I could comfortably still develop C++ in a Asus 1215B netbook with 8 GB and SSD, thanks to all the native libraries I could install, and make use via pkgconfig, the same could not be said to play around with Rust on the same netbook.

This matters, because not everyone can afford top of the line desktops, especially in 2nd and 3rd level countries, which then plays a role in language adoption.

Some even make do with what they can run on tablets.

I don't think I really agree with that. You can make do with less powerful machines in Rust too. Until this year I was using a 12 year old quad core machine that was only a bit faster than a RPi 5.

I think the biggest issue is actually disk space. C++ isn't exactly efficient with disk space but Rust is on another level. You're going to run out of disk space on that netbook it you have any more than like 2 Rust projects built.

On that netbook, this tiny Gtk Rust application took about 10 minutes from a git clone.

https://github.com/pjmlp/gwc-rs

The original C++ versions was done in 2 minutes, because it spent zero minutes compiling all dependencies.

Needlees to say that first compilation had an impact on battery charge as well.

Naturally on such a beefy machine it will fly given how fast Bevy gets compiled.

> 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.

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.

> 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 feature that either attracts or repels people to/from Rust ;)

> what's a single concept in C (e.g. "the pointer") easily has a dozen specialized equivalents in Rust

That "the pointer" is a single concept in C is the root cause of absurd numbers of bugs over the history of C.

The questions of how long the memory a pointer points to lives, what threads it is safe to access from, and how it is allocated and destroyed all still exist in C. Those answers are just implicit rather than explicit like they are in Rust. It's not like Python/etc where you don't have to worry about these things.

A reasonably smart C compiler that has visibility on all code in a project could infer a lot of that information from how the pointer is used in the wider codebase (basically what static analyzers are doing by reconstructing control flows). Of course such an extensive analysis would result in even worse compile times than Rust ;)
> 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.

Of all the things I expected to read today on HN, "I chose a programming language that appeals to my political leanings" was certainly not one of them.
With the use of quotes there, you've put those words in my mouth. I didn't say that.

What I am trying to express with the statement you refer to is that zig appeals to me on an aesthetic level. It suits my tastes.

I mentioned liberty because I appreciate that zig allows me to have complete control of memory allocations, and gives me quite a deal of control over the metal. I like this and I like that I don't have to appease a borrow checker. Zig's compiler and type system is strict enough to guide me to correctness, but the experience, broadly, is not so onerous that programming becomes tedious and frustrating.

These qualities, I suspect, resonate with my individualistic tendencies.

With respect, it's difficult to interpret "libertarian sensiblities" as something else than "political leanings". Now "liberal" is a much more general -- I wouldn't necessarily call that political -- but what you said had a strong political connotation, hence my comment.

Your explanation lands otherwise. I can't relate to "I don't have to appease a borrow checker" though. That reads like a deliberately uncharitable read of what Rust's compiler is doing. That being said, it's definitely not for everyone.

I tried Zig. Loved it. But then after a few weekends I said to myself: "Wait a bit. I've been down this path before with C and C++. I know exactly where it ends." -- and bailed.

To me these days low-level programming is basically: either go all the way, or don't go at all. Sadly Rust is not like, going really all the way, but it's IMO the closest we got. And before somebody starts enumerating obscure languages that barely have a community: I include multi-axial evaluation here i.e. PL features, stdlib, ecosystem, richness of education (Rust has _a lot_ of good books and courses), and others I am surely forgetting at the moment.

Zig is great. But I'll not take marginal improvements anymore. Not in my personal life and not in my work. I'll get big ones, or not get them.

Since we are explaining philosophies, now without political undertones: that's mine.

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…
Sometimes we have no option, given the industry standards that expect C or C++.

Khronos, Open Group, NVidia, Microsoft, Sony, Nintendo... aren't going to change their APIs and SDKs, just because of social media discussions on the merits of C, C++ vs other safer alternatives.

I agree we should minimise their use, however not everyone accepts a dual language approach, nor there are alternatives in such domains, even if they technically exist, you still need to overcome the human and political factors.

Hence why it is so relevant to fix C and C++ security flaws to some extent as well.

Obviously my comment of irresponsibility was “given that there is a choice”

Though that’s one nice thing about Swift: it has a very good interop’ with C now, and a “starting to get pretty good” interop’ with C++. So that can help, sometimes. (Obviously, I reiterate, I understand there are situations where the choice is just not possible, and enhancing C and C++ is indeed a good thing.)

The nice thing about Swift, or Java/Kotlin on Android, is the platform owner attitude, either adopt it, or go elsewhere, that is the only way safety improvements are pushed into mainstream.
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
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.

Well annotated code is fine in Python too.
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.

(comment deleted)
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.

I don't disagree that I think that the Rust project could do more to make this kind of development easier, and it is true that it doesn't come for free. That doesn't change the point that if you want to, you can do it, it is not a fundamental language limitation.
It is a fundamental language limitation, unless you want to claim that the core library (or rather what's left when using no_std) is not part of the language.

The problem comes from a combination of three things:

1. Rust's standard library (including core) likes to panic a lot, e.g. for code that is genuinely unreachable (and this is fine)

2. Rust/LLVM cannot always optimize unreachable code away (and this is also fine)

3. The presence of at least one panic causes Rust to also include the error string format machinery, which is HUGE (and this is completely unavoidable)

Because of #2, there is no way to prevent this for larger code. I can define my own panic handler, but I can't prevent panic!() calls from inside core from constructing the format message using core::fmt before they call my panic handler.

And so any non-trivial code sometimes just randomly becomes 3x larger, and I can no longer fit it on my MCU, despite never actually printing or caring about any panic messages.

I think we just disagree about what "fundamental" means. If you don't use panics, you don't get the machinery. This means it's not fundamental.

What you're talking about is the ease of which you can not include the panic machinery. I agree that it is not always easy to keep out, and that I would like if it were to be made easier.

But people are doing real, commercial projects on MCUs your size and smaller.

> If you don't use panics, you don't get the machinery.

I'm not using panics, and yet I'm getting the machinery. That is where my frustration is coming from.

On that universe you would be better off with BASIC or Pascal compilers than Rust, which would already be safer than C, while offering similar sizes.

Mikroe has C, Pascal and BASIC compilers for all kinds of microcontrollers, that is their main market.

> 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++

Rust is just as fast as C++.

yeap, unfortunately, only few can see this.
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.

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 code around borrow checker restrictions, while C++ lets you 'cheat' without having to fall back to helper types that incure runtime overhead.
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.

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

I don’t know what you’re referring to. Unsafe seems pretty well defined for 99% of use cases. Unsafe blocks allow you to dereference raw pointers and call unsafe functions. Thats about it. Remarkably, even in codebases which need a lot of unsafe (eg the kernel), almost all code is safe code.
> over/underflow checks.

Integer overflows are not checked in release builds by default, since they are not related to memory safety.

On the other hand, rust emits noalias everywhere, which helps in autovectorization.

Yep. And array bounds checks have a miniscule performance impact at runtime because they're so friendly to branch prediction.
It depends what kind of hot loop you have.
If you have a hot loop where it matters, you can put an assert outside the loop which lets llvm remove the bounds checks. Or use unsafe { get_unchecked() } to remove the bounds check entirely.
Exactly, yes. I know it's possible, of course it's possible, its just not trivial like it is in C++.

Most developers I have met don't know how to use a profiler, so not sure any of this discussion matters at all anyway, but I feel like it's important to note when the default in Rust is safe, whereas the default in C++ is fast (and more or less unsafe)

Eh, that argument cuts both ways. Lots of the defaults in C++ are bad. Like, most people don’t know how compiling all your code in a single code unit will improve performance. Or how to do it. In rust it’s a single flag in cargo.toml which is widely talked about. Rust has a much better, faster standard library than C++. Any code which makes heavy use of - for example - sorting in C++ and rust will favour rust because it uses a better algorithm by default.

Rust had the opportunity to iterate on C++’s default choices and improve on them in many cases. I’m not convinced that naive C++ is particularly efficient.

(That said, lots of rust beginners make heavy use of Box and clone() and write inefficient programs that way. It’s hard to actually measure average, beginner code.)

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

Just use unsafe then
I said rust is just as fast as C++. Not safe rust. Use unsafe where it’s appropriate, obviously.
> 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).

Market share, IDE and graphics tooling, and industry standards.

LLVM is not going to take PRs written in Rust to fix the Rust compiler backend, for example.

Neither are OpenJDK, .NET, V8, JSCore going to take such PRs.

By the way, LLVM and GCC would also not take PRs written in C.

'Industry standards' is where programming languages go to die ;)

As for PRs: well yeah of course, when in Rome...

> 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.
Im constantly surprised by the disk size required by rust builds. It takes over 50G to compile zed IIRC.
> 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.

Fortunately there are also many other memory safe languages to choose from.
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.)

> and human involvement

Isn't ironic for a project that successfully killed all past and future human involvement?

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.

Ownership is a very limiting coding constraint, and bypassing methods, when ultimately needed (e.g. cell), cannot be engineered to be ergonomical.
Rust is C++ like language, with more safety. It makes no sense to say that to get performance one can drop down to C++. As far as I am aware, you can get as fast as C with Rust. Of course, that might mean to compromise on something, some bound checks, some code ergonomics, or something else. You can write ASM in Rust, so it really gets as low level as it gets. And what I find amazing is that, similarity to C++, you can get both low level and high level code in the same language. And this is intrinsic in the language complexity: if you take a simpler language with a less powerful type system (C-class languages), you lose this ability.
This comment makes no sense. For one, "you need the absolute best performance and you decide to drop to down to C++", no, C++ and Rust are virtually equivalent in that they pretty much expose the underlying machine fully; if anything Rust makes it easier to write idiomatic performant code.

For two, there are plenty of reasons to use C++ unfortunately: compatibility with existing code based and availability of developers to name two.

> In Bun v1.3.14, every build leaks about 3 MB, forever

I'm sorry but that is insane, how was this never fixed before the rewrite?

I've been impacted by a couple of bugs in Bun.SQL and lo and behold these were only fixed for 1.4. Presumably Claude could have fixed those in the Zig version but the Bun team decided to not do that.

Furthermore, there's no mention of an LTS plan for the Zig version. It seems that if a CVE is discovered in the future, Bun users will no have no option than to update to the Rust port.

This is not how you run a project that others depend on and enough for me to not touch Bun ever again.

I'm a little puzzled: Why should you care? The language in which Bun is written isn't part of its API, if you will. You care that you have something that does various javascripty things according to a particular spec of what it's supposed to do. If a bug is fixed in 1.4.x it's fixed, why should it matter, really, if that's in Zig or Rust?
Who in their right mind would immediately migrate their production apps into a complete re-write of a runtime?

It would be naive to think there aren't new bugs or changes in behavior introduced in 1.4.

(Well, the answer is "Anthropic, with claude code", but I'm not in possession of material information related to whether they are or are not in their right minds.)

But yes, of course there will be new bugs. But that's why 1.4.x for x > 0 is interesting. If the branch is being used and people are not reporting _more_ bugs, and the bugs you care about it are being fixed (successfully) on it, and it passes your tests, etc., ... I dunno. This is an application domain where you can do some pretty solid testing of it, comparative fuzzing, etc., so it doesn't strike me as entirely mad to jump over after a few minor releases where you can see the bug trajectory.

> Well, the answer is "Anthropic, with claude code"

Anthropic is not exactly the hallmark of engineering excellence... quite the contrary.

> But yes, of course there will be new bugs

Obviously, which is why more thought should have been put into the transition.

Not everyone will want to yolo their production projects into such a massive rewrite overnight.

> Historically, rewrites are a terrible idea.

This changed for me over the last 5 years.

The first scenario was joining a company where a software product barely worked. We did the traditional incremental refactoring / rewriting, but eventually learned how rotten the core was that rewriting from first principles was the best path forward.

The lesson learned here is that the conventional wisdom probably only applies to rewriting complex but working systems.

Then multiple scenarios in the agentic coding age. Between day jobs and hobbies I've reproduced major chunks of complicated software like Salesforce, Gmail, Pioneer Rekordbox with very lean teams.

Much like the blog post, the trick is to get an excellent verification loop with a compiler, linter, and test harness / test suite around the core behaviors.

It's feeling more and more that designing and implementing comprehensive test harnesses is the real work, once you have that let the LLM cook.

I think the same, it's possible our job will morph into "coding agent herders". In this case I guess the test harnesses, linters, workflows, etc will be our herding dogs.
"I used a pre-release version of Claude Fable 5 for much of the Rust rewrite."

It'd be interesting if Anthropic became a general software company just because they have access to models that aren't yet released, possibly export-banned.