我们为什么用 Zig 构建 Lightpanda
Why we built Lightpanda in Zig

原始链接: https://lightpanda.io/blog/posts/why-we-built-lightpanda-in-zig

## Lightpanda 与 Zig 的选择 Lightpanda,一款用于自动化的网页浏览器,的开发者选择了编程语言 Zig,而非 C++、Rust 甚至 Go,主要原因是它的**简洁性**。他们认为 C++ 对于小型团队来说过于复杂,而 Rust 的安全特性带来了一些不必要的阻力,尤其是在与现有的 C++ 库(如 Chrome 的 JavaScript 引擎 V8)集成时。Go 缺乏必要的底层控制,无法实现最佳性能。 Zig 提供了一个理想的平衡点:**高性能、现代工具和更简单的学习曲线**。 显式内存分配器(允许为每个网页进行高效的区域分配)、编译时元编程(减少样板代码)以及与 C 的无缝互操作等关键特性被证明非常有价值。 尽管 Zig 仍处于 1.0 版本之前并不断发展,但该团队对其潜力充满信心,并提到了不断壮大的社区和令人印象深刻的编译时间。他们强调 Zig 清晰、显式的设计——避免隐藏的控制流和分配——是一个主要优势。最终,Zig 使小型团队能够构建一个复杂的浏览器,并拥有易于管理的源代码库和清晰的思维模型。

## Lightpanda 用 Zig 构建:一则黑客新闻讨论总结 最近一则黑客新闻帖子详细介绍了 Lightpanda (lightpanda.io) 的开发者选择 Zig 作为编程语言的原因。核心讨论围绕着语言选择是否重要,特别是对于公开访问的 Web 服务。 一个主要担忧是 Zig 中手动内存管理的安全隐患,与 Rust 等语言形成对比。然而,许多评论者承认语言选择通常反映了更广泛的工程理念,并且可以吸引特定的技术人才。一些人认为,精心选择的语言可能是良好产品决策的领先指标,并以 Bun(用 Zig 构建)为例。 虽然大多数人同意最终用户并不关心*使用什么*语言,但开发者指出它会影响性能(例如 Zed 使用 Rust),并且对于开发者工具来说可能是一个重要因素。最终,共识倾向于语言选择是成功的贡献因素,但并非保证,还需要产品与市场契合度以及一支技术娴熟的团队等关键要素。 许多评论员也指出,最近有一种趋势,项目会明确宣传它们使用 Rust、Go 或 Zig。
相关文章

原文

Because We're Not Smart Enough for C++ or Rust

Why We Built Lightpanda in Zig

TL;DR

To be honest, when I began working on Lightpanda, I chose Zig because I’m not smart enough to build a big project in C++ or Rust.

I like simple languages. I like Zig for the same reasons I like Go, C, and the KISS principle. Not just because I believe in this philosophy, but because I’m not capable of handling complicated abstractions at scale.

Before Lightpanda, I was doing a lot of Go. But building a web browser from scratch requires a low-level systems programming language to ensure great performance, so Go wasn’t an option. And for a project like this, I wanted more safety and modern tooling than C.

Why We Built Lightpanda in Zig

Our requirements were performance, simplicity, and modern tooling. Zig seemed like the perfect balance: simpler than C++ and Rust, top-tier performance, and better tooling and safety than C.

As we built the first iterations of the browser and dug deeper into the language, we came to appreciate features where Zig particularly shines: comptime metaprogramming, explicit memory allocators, and best-in-class C interoperability. Not to mention the ongoing work on compilation times.

Of course it’s a big bet. Zig is a relatively new language with a small ecosystem. It’s pre-1.0 with regular breaking changes. But we’re very bullish on this language, and we’re not the only ones: , , , and are all building with Zig. And with , big tech is taking notice.

Here’s what we’ve learned.

What Lightpanda Needs from a Language

Before diving into specifics, let’s talk about what building a browser for web automation requires.

First, we needed a JavaScript engine. Without one, a browser only sees static HTML: no client-side rendering and no dynamic content. We chose V8, Chrome’s JavaScript engine, because it’s state of the art, widely used (, ), and relatively easy to embed.

V8 is written in C++, and doesn’t have a C API, which means any language integrating with it must handle C++ boundaries. Zig doesn’t interoperate directly with C++, but it has first-class C interop, and C remains the lingua franca of systems programming. We use C headers generated primarily from , part of the , to bridge between V8’s C++ API and our Zig code.

Beyond integration, performance and memory control were essential. When you’re crawling thousands of pages or running automation at scale, every millisecond counts. We also needed precise control over short-lived allocations like DOM trees, JavaScript objects, and parsing buffers. Zig’s explicit allocator model fits that need perfectly.

Why Not C++?

C++ was the obvious option: it powers virtually every major browser engine. But here’s what gave us pause.

  • Four decades of features: C++ has accumulated enormous complexity over the years. There are multiple ways to do almost everything: template metaprogramming, multiple inheritance patterns, various initialization syntaxes. We wanted a language with one clear way to do things.
  • Memory management: Control comes with constant vigilance. Use-after-free bugs, memory leaks, and dangling pointers are real risks. Smart pointers help, but they add complexity and runtime overhead. Zig’s approach of passing allocators explicitly makes memory management clearer and enables patterns like arenas more naturally.
  • Build systems: Anyone who’s fought with CMake or dealt with header file dependencies knows this pain. For a small team trying to move quickly, we didn’t want to waste time debugging build configuration issues.

We’re not saying C++ is bad. It powers incredible software. But for a small team starting from scratch, we wanted something simpler.

Why not Rust?

Many people ask this next. It’s a fair challenge. Rust is a more mature language than Zig, offers memory safety guarantees, has excellent tooling, and a growing ecosystem.

Rust would have been a viable choice. But for Lightpanda’s specific needs (and honestly, for our team’s experience level) it introduced friction we didn’t want.

The Unsafe Rust Problem

When you need to do things the borrow checker doesn’t like, you end up writing unsafe Rust, which is surprisingly hard. from explores this in depth in his article .

Browser engines and garbage-collected runtimes are classic examples of code that fights the borrow checker. You’re constantly juggling different memory regions: per-page arenas, shared caches, temporary buffers, objects with complex interdependencies. These patterns don’t map cleanly to Rust’s ownership model. You end up either paying performance costs (using indices instead of pointers, unnecessary clones) or diving into unsafe code where raw pointer ergonomics are poor and Miri becomes your constant companion.

Zig takes a different approach. Rather than trying to enforce safety through the type system and then providing an escape hatch, Zig is designed for scenarios where you’re doing memory-unsafe things. It gives you tools to make that experience better: non-null pointers by default, the GeneralPurposeAllocator that catches use-after-free bugs in debug mode, and pointer types with good ergonomics.

Why Zig Works for Lightpanda

Zig sits in an interesting space. It’s a simple language that’s easy to learn, where everything is explicit: no hidden control flow, no hidden allocations.

Explicit Memory Management with Allocators

Zig makes you choose how memory is managed through allocators. Every allocation requires you to specify which allocator to use. This might sound tedious at first, but it gives you precise control.

Here’s what this looks like in practice, using an arena allocator:

This pattern matches browser workloads perfectly. Each page load gets its own arena. When the page is done, we throw away the entire memory chunk. No tracking individual allocations, no reference counting overhead, no garbage collection pauses. (Though we’re learning that single pages can grow large in memory, so we’re also exploring mid-lifecycle cleanup strategies). And you can chain arenas, to create short-lived objects inside a page lifecycle.

Compile-Time Metaprogramming

Zig’s comptime feature lets you write code that runs during compilation. We use this extensively to reduce boilerplate when bridging Zig and JavaScript.

When integrating V8, you need to expose native types to JavaScript. In most languages, this requires glue code for each type. To generate this glue you need some code generation, usually through Macros (Rust, C, C++). Macros are a completely different language, which has a lot of downsides. Zig’s comptime lets us automate this:

The registerType function uses comptime reflection to:

  • Find all public methods on Point
  • Generate JavaScript wrapper functions
  • Create property getters/setters for x and y
  • Handle type conversions automatically

This eliminates manual binding code and makes adding new types simple by using the same language at compile time and runtime.

C Interop That Just Works

Zig’s C interop is a first-class feature: you can directly import C header files and call C functions without wrapper libraries.

For example, we use cURL as our HTTP library. We can just import libcurl C headers in Zig and use the C functions directly:

It feels as simple as using C, except you are programming in Zig.

And with the build system it’s also very simple to add the C sources to build everything together (your zig code and the C libraries):

This simplicity of importing C mitigates the fact that the Zig ecosystem is still small, as you can use all the existing C libraries.

The Build System Advantage

Zig includes its own build system written in Zig itself. This might sound unremarkable, but compared to CMake, it’s refreshingly straightforward. Adding dependencies, configuring compilation flags, and managing cross-compilation all happen in one place with clear semantics. Runtime, comptime, build system: everything is in Zig, which makes things easier.

Cross-compilation in particular is usually a difficult topic, but it’s very easy with Zig. Some projects like use Zig mainly as a build system and toolchain.

Compile times matter

Zig compiles fast. Our full rebuild takes under a minute. Not as fast as Go or an interpreted language, but enough to have a feedback loop that makes development feel responsive. In that regard, Zig is considerably faster than Rust or C++.

This is a strong focus of the Zig team. They are also a small team and they need fast compilation for the development of the language, as Zig is written in Zig (self-hosted). For that purpose, they are developing native compiler backends (i.e. not using LLVM), which is very ambitious and yet successful: it’s already the default backend for x86 in debug mode, with a significant improvement in build times (). And is on its way.

What We’ve Learned

After months of building Lightpanda in Zig, here’s what stands out.

  • The learning curve is manageable. Zig’s simplicity means you can understand the entire language in a few weeks. Compared to Rust or C++, this makes a real difference.
  • The allocator model pays off. Being able to create arena allocators per page load, per request, or per task gives us fine-grained memory control without tracking individual allocations.
  • The community is small but helpful. Zig is still growing. The Discord community and are active, and the language is simple enough that you can often figure things out by reading the standard library source.

Conclusion

Lightpanda wouldn’t exist without the work of the Zig Foundation and the community behind it. Zig has made it possible to build something as complex as a browser with a small team and a clear mental model, without sacrificing performance.

  • If you’re curious about Zig’s design philosophy or want to see how its compiler and allocator model work, the is the best place to start.
  • You can also explore the and follow the project on GitHub
  • to test the cloud version

FAQ

Is Zig stable enough for production use?

Zig is still pre-1.0, which means breaking changes can happen between versions. That said, we’ve found it stable enough for our production use, especially since the ecosystem has largely standardized on tracking the latest tagged releases rather than main. The language itself is well-designed, and most changes between versions are improvements that are worth adapting to. Just be prepared to update code when upgrading Zig versions.

What’s the hardest part about learning Zig?

The allocator model takes adjustment if you’re coming from garbage-collected languages. You need to think about where memory comes from and when it gets freed. But compared to Rust’s borrow checker or C++‘s memory management, it’s relatively straightforward once you understand the patterns.

Can Zig really replace C++ for browser development?

For building a focused browser like Lightpanda, yes. For replacing Chromium or Firefox, that’s unlikely: those projects have millions of lines of C++ and decades of optimization. We’re more likely to see Rust complementing C++ in those projects over time, for example how Firefox is leveraging . But for new projects where you control the codebase, Zig is absolutely viable.

Where can I learn more about Zig?

Start with the . The site provides practical tutorials. And join the community on or where developers actively help newcomers. The language is simple enough that reading standard library source code is also a viable learning approach.


Francis previously cofounded BlueBoard, an ecommerce analytics platform acquired by ChannelAdvisor in 2020. While running large automation systems he saw how limited existing browsers were for this kind of work. Lightpanda grew from his wish to give developers a faster and more reliable way to automate the web.

联系我们 contact @ memedata.com