zackoverflow

I spent 181 minutes waiting for the Zig compiler this week

TLDR; The Zig compiler takes about 1 minute and 30 seconds to compile debug builds of Bun. Zig's language server doesn't do basic things like type-checking, so often have to run the compiler to see if my code works.


I am a very happy Zig user. I use it to write compilers for fun, and I’ve been maining it this past 1.5 years while working on the Bun JavaScript runtime.

So I was excited to learn that Roc-lang announced they were going to rewrite their ~300k LOC compiler from Rust to Zig.

I agree with their rationale behind this decision, except for one detail: compile times.

In their writeup, they said that “Rust’s compile times are slow. Zig’s compile times are fast”:

Rust’s compile times are slow. Zig’s compile times are fast. This is not the only reason, but it’s a big reason.

Having a slow feedback loop has been a major drain on both our productivity and also our enjoyment when working on the code base. Waiting several seconds to build a single test, before it has even started running, is not enjoyable.

I’ve had exactly the opposite experience while working on Bun’s codebase.

Zig’s compile times have consistently been a thorn in my side. So I began tracking exactly how long I was waiting on the Zig compiler. Claude whipped up a script for me in seconds.

So how much time did I waste in 5 days?

181 minutes.

That’s 3 hours.

I was cumulatively waiting about 45 minutes each day.

Output of my time wasted tracking script

Writing code with long compile timesλ

Running zig build on the Bun codebase takes about 1 minutes and 30 seconds… for debug builds.

If I change something 4 times, I’ve wasted 6 minutes. If I change something 10 times, I’ve wasted 15 minutes.

This is not great for iterating on features, and makes it harder to enter and maintain flow-state either.

I’ve only mentioned debug builds… what about a release build? A release build of Bun takes upwards of 5 minutes on my fully specced out M3 MacBook.

The real problem: The language server isn’t very helpfulλ

The real issue is that zls (the defacto language server for Zig) is missing critial semantic analysis features like type-checking.

This means I spend even more time waiting on the compiler, because I need to use it just to check if my code is correct.

This issue is made worse by the fact that when Zig encounters a compiler error in a particular function scope, it will stop running semantic analysis on that scope and report it back to you.

This means that in a function scope with multiple errors, you need to discover and fix each error one by one, waiting 90 seconds in between.

This problem has been reduced somewhat, as Zig recently shipped a feature which lets you just semantic analysis on your code base. This drops it from 90 seconds to 25 seconds.

It’s better than nothing, but very very far from ideal.

Why is Zig’s compiler so slow?λ

The first thing obvious major factor is that Bun’s codebase is massive. It is currently at ~850k lines of Zig code.

The second is that each invocation of the compiler builds everything from scratch all over again. Zig has made great progress in implementing incremental compilation, but it is not fully ready yet. There is a beta version of incremental compilation available, but it does not support the usingnamespace feature. There are 534 occurences of it in the Bun codebase, so we can’t even try it, and migrating off of usingnamespace would probably take a double digit number of hours of work.

Finally, semantic analysis itself is single-threaded and is necessarily more complicated and compute heavy than other language’s because of Zig’s flagship comptime feature.

Conclusionλ

I really enjoy writing Zig code. I love it’s clean syntax, comptime, packed structs and arbitrary bit-width integers, the Allocator API, and useful data-oriented design abstractions in the standard library.

I wish the compiler were faster, and the language server actually performed semantic analysis, so I could spend less time waiting and more time writing and reading Zig code.