Zig is a simple, explicit systems programming language with no hidden work. If you’ve been developing close to the “metal” or seeking high performance for a while, you’ve probably noticed the renaissance of systems languages.
For decades, C and C++ have been the undisputed kings. But let’s be honest: C is 50 years old. It’s a legendary language, but it carries design problems that today are constant sources of vulnerabilities and headaches.
Zig was born precisely in that gap. It doesn’t seek to be “the next C++” nor “the new Rust”. Its proposal is more like rethinking C with modern tools: simplicity, clarity and explicit control.
Zig is a general-purpose language oriented towards systems programming, designed by Andrew Kelley. Its main goals are robustness, performance and clarity.
The philosophy of “zero surprises”
What truly sets Zig apart from other modern languages is not what it has, but what it DOESN’T have.
When we read code in C++, C# or even JavaScript, things often happen that we don’t see. An addition a + b could be invoking a complex operator overloading. An assignment could trigger a copy constructor. Any line could throw an exception and change the program’s flow.
Zig is based on a very simple idea: no hidden control flow.
If you see a + b in Zig, you know it’s a mathematical addition. If you see a function call, you know the flow goes there and returns.
- There is no operator overloading.
- There are no properties (hidden getters or setters).
- There are no exceptions.
This, which might seem restrictive, is a blessing when we are debugging critical systems. The code does exactly what it says it does.
No hidden memory allocations
In high-level languages (Java, Python, JS), the Garbage Collector (GC) works for us. It’s convenient, but unpredictable. In C++, constructors or the STL can allocate memory on the heap without us explicitly noticing.
In Zig, there are no hidden allocations.
Zig has no Garbage Collector. Unlike C, where the global allocator malloc exists, in Zig there is no default allocator. By convention, if a function needs to allocate memory, it receives an Allocator as a parameter.
// Conceptual example
// In Zig, you decide WHERE the memory is stored
const result = try myFunction(my_allocator, data);This gives us absolute control. Want to use the stack? A fixed memory block? The system heap? You decide.
This feature is especially useful in WebAssembly (WASM) and embedded systems, where binary size and memory control are important.
comptime: code at compile time
comptime is one of the most interesting parts of Zig, and also one that most sets it apart from C.
Most languages have two phases: compilation and execution. Zig blurs that line by allowing us to execute Zig code during compilation.
In C++ templates are typically used for metaprogramming, and in Rust, macros. In Zig we use the language itself.
We can write functions that, when compiled, generate optimized code, calculate lookup tables or validate types, all before the final program is generated.
// The initializer of a global constant is calculated at compile time.
const sine_table = generateSineTable();This allows us to do generics and metaprogramming without learning a new and strange syntax.
A tool for compiling C and C++
One of the great things about Zig is how it embraces the existing ecosystem. Zig doesn’t aim to isolate itself; it aims to integrate.
Zig can also act as a C and C++ compiler without external dependencies, with cross-compilation support. It exposes the commands zig cc and zig c++ for this purpose.
This allows us to compile existing projects and use C libraries from Zig. In Zig 0.16, header translation is preferably integrated into build.zig; we will see the complete process later in the course.
In many cases, there’s no need to write manual wrappers. Zig can translate declarations from .h files and link the corresponding library from its build system.
Why should you care?
If you work solely in web development, Zig might seem “too low-level”. Still, it might interest you for:
- Understanding how the computer actually works.
- Creating fast command-line interface (CLI) tools.
- Programming microcontrollers (like on Arduino) but with a modern language.
- Creating efficient WebAssembly (WASM) modules.
In those areas, Zig is worth our time.