I know the community was pretty split on Jared Sumner’s decision. Now, we get to read his thoughts on the move and appreciation for Zig.

sbrow July 9, 2026, 3:39am 2

Quite an interesting article, with some good prompting tips.

Pretty impressive if we take them at their word, though the number of tokens used is absurd.

It’s a shame that we’ve lost such a large project to Rust, but it sounds like they really felt the need for the borrow checker :confused:

IceGuye July 9, 2026, 3:44am 3

I think Andrew Kelley has already concluded this topic in his recent interview: https://m.youtube.com/watch?v=iqddnwKF8HQ&t=463s … He explained how other companies use Zig.

I think many of them use Zig in a way that is not what Zig is currently focusing on, or designed for. And as Zig continually growing and changing, they may eventually feel more difficult instead of easier. Then that’s the time they depart.

That’s normal.

Doesn’t matter how companies feel about Zig, to use it; ditch it; appreciate it; hate it, Zig as a charitable non profit organization, it has its missions need to follow.

gwenzek July 9, 2026, 3:59am 4

Yes, great blog worth the wait.
Feels a bit unfair that most of the “Rust gains” in terms of speed and binary size are LLVM flags they could have used to with Zig.

For the safety aspect, it seems that their problem space is inherently complicated because of the JS objects having complicated lifetimes.
I think that’s one of the hardest gotcha with Zig, is that if you do C++/Java but in Zig you’re gonna have a hard time.
But that’s style is very pervasive, even my own code has a lot of alloc(foo); defer/errdefer free(foo)
What you need is architecture your programs around a few independent arenas, but this is not what people learned and it requires more whiteboard thinking.

I hope something good comes out of it and it leads to improved Zig. Eg this issue mentionned in the blog post Block stack allocations do not disappear at end of block scope · Issue #23475 · ziglang/zig · GitHub

@gwenzek I’m a not a Zig developer but generally like following programming language development so I try to pay some attention to it. I mostly write Rust these days, so forgive me for poking at your comment in particular but I’m quite curious about a couple of things:

I feel like the same could kind of be said about C or C++, yet these runtimes and browsers obviously do exist in these languages. It is indeed an inherently tricky problem space really for any of these languages, but I’m kind of curious what you mean by this:

I understand that if you write non-idiomatic code it can lead to problems, but are you suggesting that one really just shouldn’t write a a complex event-driven system with refcounted/GC’d objects in Zig?

I’m also curious how arena allocators would generally help if you design around it. I’ve worked with a mostly pure C codebase at work that makes heavy use of arena allocators and it’s still kind of hellish to work with. Arenas may make memory management generally simpler, but from what I’ve seen does not necessarily magically fix the issue of object lifetime mismanagement and can semi-complicate the exploit mitigation story (MTE for example).

I suppose I’m not seeing how in this specific case designing with a different memory allocation strategy would have helped except maybe with the longer-lived memory leaks.

Moortu July 9, 2026, 6:04am 6

Ironically, if they had initially written in any other language, it probably wouldnt have been ported so well by AI.

Because of zigs no magic, what you see is what you get.

I’m not a huge proponent of forcing programming styles, but I would be curious what an optional borrow checker and/or “safety” mode would look like for Zig. If the development community would be for or against it.

gwenzek July 9, 2026, 6:22am 8

My take on manual memory management is “it’s hard unless if you have 5 objects”. So I group everything in arenas and think about my 5 arenas.

IDK how well this applies to Bun
Having a few refcounted object seems OK, but it should be clear which objects are ref counted.

One of the main points Jared makes against Zig seems to be that you have to remember to clean things up. The C++ and Rust alternatives are to make cleanup implicit. I don’t think I’ve seen a language in the middle which both enforces cleanup, but does so by requiring the code to explicitly declare how (rather than implicitly).

This is an interesting insight. My Zig answer for to deal with complicated memory management is to not have complicated memory management. This is not an excuse for Zig - complicated memory management is also slower, so there are real benefits for not having it. However, if your goal is to implement another language which does have complicated lifetimes, you have to eat that cost somewhere. I suspect that starting as a line for line rewrite of older non-Zig code didn’t help set the precedents which would make this easier.

I’ve never gone down this route myself, but there are high safety requirement areas of coding which require proofs of correctness along with the code. That’s somewhat close to what you’re asking about.

The section on having claude write up a guide on lifetimes does raise one question: Could claude have instead simply worked through the Zig code, providing proofs for lifetime correctness (or fixes where it was wrong)? If I were not sticking my head in the sand in regards to ai programming, my focus would be on using to bridge the gap from high level specification to low level code through proof of correctness.

floooh July 9, 2026, 7:30am 11

An interesting (and tbh somewhat disappointing) tidbit I didn’t know before is that the original Bun was a line-by-line port of esbuild from Go to Zig…

Also at $165.000 token cost I wonder if the better approach would have been to write a much smaller Zig-to-Rust transpiler (or a ‘Rust backend’ for the Zig compiler heh), even if vibe-coded.

I also keep wondering why a wrapper around JavaScriptCore needs a million lines of code.

Anyway…

Because these “runtimes” do way more than that.

Bun is a:

  • transpiler
  • minifier
  • bundler
  • package manager
  • http and websocket slient
  • and implements host machine access (which is a huge API surface): All | Node.js v26.5.0 Documentation (this API could very well be good enough to act as an OS API)

Just providing seamless host API across different operating systems, while not giving up on performance is a huge job on it’s own. And you need even more code on tests to make sure it keeps working as the world moves forward.

I don’t think any of these things explain why it needs a million lines of code?

I found the whole “Bun is better in Rust” section to be a bit disingenuous. They present the “improvements” as if they are only possible because of Rust. But the binary size change, speed increase, etc. are things that any good rewrite would achieve (assuming a like-for-like language swap). To claim that Rust has some special properties that magically unlocked performace is a farce.

Also, reduced memory usage has nothing to do with defer vs Drop and everything to do with how you are writing the code. A good rewrite would improve this, even if it was just a rewrite in Zig or C/C++. When one first writes some code, one often doesn’t know the memory patterns and if one doesn’t refactor then it can get out of hand.

We fixed every instrumentable memory leak
We improved Bun’s LeakSanitizer integration to track all native code memory allocations.

Also disingenuous. This is not unique to Rust. Could have also done this with Zig/C.

IceGuye July 9, 2026, 3:35pm 16

Not sure if many people noticed that we now have a SafeAllocator in 0.17. Zig Documentation

All leaks will be reported. All double free and operation races will panic or segfault.

Most write after free will panic or segfault.

And it’s lock free thread safe, so you can pass the allocator along threads.

Since it addresses races and write after free and it’s thread safe, it’s more or less a more humane answer to borrow checker.

Also this is more explicit than the implicit drop.

And also, it can be backed by any allocator, unlike the DebugAllocator (the old GPA) always with page_allocator. So if you deal with a lot of C codes, you can use c_allocator as the backing allocator.

And also when it is backing the Arena allocator, the arena is lock free thread safe too.

With all those helps from the allocator, I can’t imagine how he still forgets to free memory, and he worries about overly abuse defer free… If his program has billions of syscall heap allocation and free, and if his program has billions of race and mutated writing and write after free, he probably would abuse Vec, String, HashMap with Rc RefMut or Arc Mutex if he wrote Bun in Rust from the very beginning…

I agree with someone here just said: it’s not the Rust that saves him, it’s the AI rewrite to help him to refactor his codes, doesn’t matter which language he uses.

Also I don’t think those “I want to see Zig’s answer to Rust’s blabla feature” is a viable way of choosing languages. I have never seen people waiting Rust’s answer to Pony’s strict lock free multi threading policy, so why another language will need to answer Rust, although many features have already given an answer.

I might be missing something, but you can set a backing allocator on DebugAllocator.backing_allocator

This is really more analogous to ASAN. With this model you are still required to exercise the condition at runtime to trigger it, and you are paying a cost somewhere. The borrow checker prevents it from ever happening, even if you code has no practical possibility of the bug happening.

I find it a bit insane to see suggestions that the allocation strategies or “use a different” allocator are recommended. That does not scale. Full stop.

One of my main issues, maintaining a larger project, is that we have nothing that can be used for non-std.mem.Allocators (e.g. MemoryPool, allocator for GPU, File objects)

Does anyone know if and how the borrow checker can even work when Rust is used to implement a VM for a GC language?

I mean, I cannot imagine how that should work at all for the JS objects, because their lifetimes are determined by the dynamic nature of the running VM, not by the static VM implementation.

I’m using Zig to develop a bytecode VM with GC for a JS-like language, which started as Lox last year. Using the DebugAllocator together with the “stress GC” option (perform GC before each and every alloc) helped me a lot to fix all GC bugs so far (and I developed some kind of instinct for this topic).

So, from my experience so far, I think it would have been possible to catch at least most of the memory bugs in Bun with Zig as well.

However, I avoided multi-threading in my VM so far, because that could open a whole new world of race condition issues.