back

by Philpax·1mo ago·view on hn ↗
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%.
15 comments
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.
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>"?

Would love to follow your journey!
> 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.
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 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.
That's what I always did pre LLM, it was fine
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.

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.
A sophisticated rewrite? Sure. This was a naive like-for-like rewrite, though.
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.
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.
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 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.
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.

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?
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.
I find Rust more readable than zig
you're not alone.
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.
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 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.

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