Zig (programming language)
{{Short description|General-purpose programming language}}
{{Infobox programming language
| name = Zig
| logo = Zig logo 2020.svg
| logo_size = 200px
| paradigms = Multi-paradigm: imperative, concurrent, procedural, functional
| designer = Andrew Kelley
| released = {{Start date and age|2016|02|08|df=yes}}{{cite web |last1=Kelley |first1=Andrew |title=Introduction to the Zig Programming Language |url=https://andrewkelley.me/post/intro-to-zig.html |website=andrewkelley.me |access-date=8 November 2020}}
| latest release version = {{wikidata|property|reference|edit|Q51885456|P348}}
| latest release date = {{Start date and age|{{wikidata|qualifier|Q51885456|P348|P577}}}}
| latest preview version =
| latest preview date =
| typing = Static, strong, inferred, structural, generic
| memory management = Manual
| programming language = Zig
| platform = x86-64, ARM64, WebAssembly
Tier 2: ARM, IA-32, RISC-V, MIPS64, POWERPC64, SPARC64, some tier-2 platforms have tier-1 support for standalone programs
| operating system = Cross-platform: Linux, macOS, FreeBSD, Windows
| license = MIT
| file ext = .zig, .zir, .zigr, .zon
| website = {{url|https://ziglang.org/}}
| influenced by = C, C++, LLVM IR, Go, Rust{{cite web | url=https://news.ycombinator.com/item?id=37447780 | title=What are the pros and cons of Zig vs Rust? I see Zig mentioned more and more her... | Hacker News }}
{{cite web | url=https://www.youtube.com/watch?v=5_oqWE9otaE | title=What’s Zig got that C, Rust and Go don’t have? (With Loris Cro) | website=YouTube | date=15 November 2023 }}
https://news.ycombinator.com/item?id=25797025
{{cite web | url=https://ziglang.org/learn/overview/ | title=Overview ⚡ Zig Programming Language }}
}}
Zig, also known as Ziglang, {{Cite web |title=Home ⚡ Zig Programming Language |url=https://ziglang.org/ |access-date=2024-12-31 |website=ziglang.org}} is an imperative, general-purpose, statically typed, compiled system programming language designed by Andrew Kelley.{{Cite web |date=2021-10-19 |title=Taking the warts off C, with Andrew Kelley, creator of the Zig programming language |url=https://sourcegraph.com/podcast/andrew-kelley |access-date=2024-04-18 |website=Sourcegraph |language=en}} It is free and open-source software, released under an MIT License.{{Cite web|url=https://github.com/ziglang/zig|title=ziglang/zig|website=GitHub|language=en|access-date=2020-02-11}}
A major goal of the language is to improve on the C language{{Cite web|url=https://ziglang.org/#Zig-competes-with-C-instead-of-depending-on-it|title=The Zig Programming Language|website=Ziglang.org|access-date=2020-02-11}} (also taking inspiration from Rust{{Cite web |title=Zig programming language |url=https://sudonull.com/post/3683-Zig-programming-language |access-date=2020-02-11 |website=SudoNull |language=en}}{{sfn|Yegulalp|2016}}), with the intent of being even smaller and simpler to program in, while offering more functionality.{{Cite web |date=2017-10-31 |title=Zig has all the elegant simplicity of C, minus all the ways to shoot yourself in the foot |url=https://jaxenter.com/zig-language-kelley-interview-138517.html |archive-url=https://web.archive.org/web/20171101231710/https://jaxenter.com/zig-language-kelley-interview-138517.html |archive-date=2017-11-01 |access-date=2020-02-11 |website=JAXenter |language=en-US}} The improvements in language simplicity relate to flow control, function calls, library imports, variable declaration and Unicode support. Further, the language makes no use of macros or preprocessor instructions. Features adopted from modern languages include the addition of compile time generic programming data types, allowing functions to work on a variety of data, along with a small set of new compiler directives to allow access to the information about those types using reflective programming (reflection).{{Cite web|url=https://ziglang.org/|title=The Zig Programming Language|website=Ziglang.org|access-date=2020-02-11}} Like C, Zig omits garbage collection, and has manual memory management. To help eliminate the potential errors that arise in such systems, it includes option types, a simple syntax for using them, and a unit testing framework built into the language. Zig has many features for low-level programming, notably packed structs (structs without padding between fields), arbitrary-width integers{{Cite web |url=https://www.theregister.co.uk/2020/04/24/llvm_project_adds_support_for/ |title=Keen to go _ExtInt? LLVM Clang compiler adds support for custom width integers |last1=Anderson |first1=Tim |date=2020-04-24 |website=www.theregister.co.uk |language=en |access-date=2024-12-30}} and multiple pointer types.{{Cite web|url=https://ziglang.org/documentation/master/|title=Documentation|website=Ziglang.org|access-date=2020-04-24}}
The main drawback of the system is that, although Zig has a growing community, as of 2025, it remains a new language with areas for improvement in maturity, ecosystem and tooling.{{cite web |last=Chigozie |first=Oduah |title=Comparing Rust vs. Zig: Performance, Safety, and More |url=https://blog.logrocket.com/comparing-rust-vs-zig-performance-safety-more/ |website=LogRocket Blog |date=2024-06-04 |access-date=2024-07-16}} Also the learning curve for Zig can be steep, especially for those unfamiliar with low-level programming concepts. The availability of learning resources is limited for complex use cases, though this is gradually improving as interest and adoption increase. Other challenges mentioned by the reviewers are interoperability with other languages (extra effort to manage data marshaling and communication is required), as well as manual memory deallocation (disregarding proper memory management results directly in memory leaks).
The development is funded by the Zig Software Foundation (ZSF), a non-profit corporation with Andrew Kelley as president, which accepts donations and hires multiple full-time employees.{{Cite web |title=Jakub Konka on Twitter |url=https://twitter.com/kubkon/status/1377146321136537602 |archive-url=https://web.archive.org/web/20220410102319/https://twitter.com/kubkon/status/1377146321136537602 |archive-date=2022-04-10 |access-date=2021-05-28 |website=Twitter |language=en}}{{Cite web|title=Announcing the Zig Software Foundation|url=https://ziglang.org/news/announcing-zig-software-foundation/|access-date=2021-05-28|website=Ziglang.org}}{{Cite web|title=Sponsor ZSF|url=https://ziglang.org/zsf/|access-date=2021-05-28|website=Ziglang.org}} Zig has very active contributor community, and is still in its early stages of development.{{cite web |url = https://thenextweb.com/news/zig-highest-paying-programming-language |title = Why Zig has become the highest-paying programming language |last =Kavanagh |first =Amanda |date = June 25, 2024 |website=The Next Web |accessdate=Dec 15, 2024}} Despite this, a Stack Overflow survey in 2024 found that Zig software developers earn salaries of $103,000 USD per year on average, making it one of the best-paying programming languages.{{cite web |url = https://venturebeat.com/programming-development/3-programming-languages-you-need-to-know-about/ |title = 3 programming languages you need to know about |last = McBride |first = Aoibhinn |date = July 16, 2024 |website=VentureBeat |accessdate = Dec 15, 2024}} However, only 0.83% reported they were proficient in Zig.
Language
=Goals=
The primary goal of Zig is to be a better solution to the sorts of tasks that are currently solved with C. A primary concern in that respect is readability; Zig attempts to use existing concepts and syntax wherever possible, avoiding the addition of different syntax for similar concepts. Further, it is designed for "robustness, optimality and maintainability", including a variety of features to improve safety, optimization, and testing. The small and simple syntax is an important part of the maintenance, as it is a goal of the language to allow maintainers to debug the code without having to learn the intricacies of a language they might not be familiar with.{{sfn|Elizabeth|2017}} Even with these changes, Zig can compile into and against existing C code; C headers can be included in a Zig project and their functions called, and Zig code can be linked into C projects by including the compiler-built headers.{{sfn|Yegulalp|2016}}
In keeping with the overall design philosophy of making the code simple and easy to read, the Zig system as a whole also encompasses a number of stylistic changes compared to C and other C-like languages. For instance, the Rust language has operator overloading which means a statement like {{code|a {{=}} b + c}} might actually be a function call to a type’s overloaded version of the plus operator. Further, that function might panic which might pre-empt any following code. In Zig, if something calls a function, it looks like a function call; if it doesn’t, it doesn’t look like a function call. If it can raise an error, it is explicit in the syntax,{{sfn|Yegulalp|2016}} error handling is handled through error types and can be handled with {{code|catch}} or {{code|try}}.
The goals of Zig are in contrast to those of many other languages designed in the same time period, like Rust, Carbon, and Nim. Generally, these languages are more complex with added features like operator overloading, functions that masquerade as values (properties), and many other features intended to aid in building large programs. These sorts of features have more in common with C++’s approach, and these languages are more along the lines of that language.{{sfn|Yegulalp|2016}} Zig has a more conservative extension of the type system, supporting compile time generics and accommodating a form of duck typing with the {{code|comptime}} directive.
=Memory handling=
One of the primary sources of bugs in C programs is the memory management system, based on malloc. malloc sets aside a block of memory for use in the code and returns a reference to that memory as a pointer. There is no system to ensure that memory is released when the program no longer needs it, which can lead to programs using up all available memory, a memory leak. More common is a dangling pointer that does not refer to a properly allocated memory object.
A common solution to these problems is a garbage collector (GC), which examines the program for pointers to previously allocated memory, and removing any blocks that no longer have anything pointing to them. Although this greatly reduces, or even eliminates, memory errors, GC systems are relatively slow compared to manual memory management{{citation needed|date=August 2024}}, and have unpredictable performance that makes them unsuited to systems programming. Another solution is automatic reference counting (ARC), which implements the same basic concept of identifying blocks of disused memory, but does so at pointer creation and destruction time by maintaining the number of pointers to a block, meaning there is no need to perform exhaustive pointer searches, which are rendered unnecessary at the cost of adding reference counter adjustment overhead to every pointer creation and destruction operation.{{cite web |url=https://docs.elementscompiler.com/Concepts/ARCvsGC/ |title=ARC vs. GC |website=Elements}}
Zig aims to provide performance similar to or better than C, so GC and ARC are not suitable solutions. Instead, it uses a modern, {{as of|2022|lc=yes}}, concept known as option types. Instead of a pointer being allowed to point to nothing, or nil, a separate type is used to indicate data that is optionally empty. This is similar to using a structure with a pointer and a boolean that indicates whether the pointer is valid, but the state of the boolean is invisibly managed by the language and does not need to be explicitly managed by the programmer. So, for instance, when the pointer is declared it is set to "unallocated", and when that pointer receives a value from a malloc, it is set to "allocated" if the malloc succeeded.{{cite web |url=https://www.baeldung.com/java-optional |title= Guide To Java 8 Optional |date=28 November 2022}}
The advantage to this model is that it has very low or zero overhead; the compiler has to create the code to pass along the optional type when pointers are manipulated, as opposed to a simple pointer, but this allows it to directly express possible memory problems at compile time with no runtime support. For instance, creating a pointer with a null value and then attempting to use it is perfectly acceptable in C, leading to null-pointer errors. In contrast, a language using optional types can check that all code paths only attempt to use pointers when they are valid. While this does not eliminate all potential problems, when issues do occur at runtime the error can be more precisely located and explained.{{cite web |url=https://ggbaker.ca/prog-langs/content/rust-memory.html |title= Rust: Memory Management}}
Another change for memory management in Zig is that the actual allocation is handled through {{code|struct}}s describing the action, as opposed to calling the memory management functions in libc. For instance, in C if one wants to write a function that makes a string containing multiple copies of another string, the function might look like this:
const char* repeat(const char* original, size_t times);
In the code, the function would examine the size of {{code|original}} and then malloc {{code|times}} that length to set aside memory for the string it will build. That malloc is invisible to the functions calling it, if they fail to later release the memory, a leak will occur. In Zig, this might be handled using a function like:
fn repeat(allocator: std.mem.Allocator, original: []const u8, times: usize) std.mem.Allocator.Error![]const u8;
In this code, the {{code|allocator}} variable is passed a struct that describes what code should perform the allocation, and the {{code|repeat}} function returns either the resulting string or, using the optional type as indicated by the {{code|!}}, an Allocator.Error. By directly expressing the allocator as an input, memory allocation is never "hidden" within another function, it is always exposed to the API by the function that is ultimately calling for the memory to be allocated. No allocations are performed inside Zig’s standard library. Further, as the struct can point to anything, one can use alternative allocators, even ones written in the program. This can allow, for instance, small-object allocators that do not use the operating system functions that normally allocate an entire memory page.{{cite web |url=https://ziglearn.org/chapter-2/ |title=Allocators|date=11 September 2023 }}
Optional types are an example of a language feature that offers general functionality while still being simple and generic. They do not have to be used to solve null pointer problems, they are also useful for any type of value where "no value" is an appropriate answer. Consider a function {{code|countTheNumberOfUsers}} that returns an integer, and an integer variable, {{code|theCountedUsers}} that holds the result. In many languages, a magic number would be placed in {{code|theCountedUsers}} to indicate that {{code|countTheNumberOfUsers}} has not yet been called, while many implementations would just set it to zero. In Zig, this could be implemented as an {{code|var theCountedUsers: ?i32 {{=}} null|lang=zig}} which sets the variable to a clear "not been called" value.
Another more general feature of Zig that also helps manage memory problems is the concept of {{code|defer}}, which marks some code to be performed at the end of a function no matter what happens, including possible runtime errors. If a particular function allocates some memory and then disposes of it when the operation is complete, one can add a line to defer a {{code|free}} to ensure it is released no matter what happens.
Zig memory management avoids hidden allocations. Allocation is not managed in the language directly. Instead, heap access is done via the standard library, explicitly.{{Cite news |last=Tyson |first=Matthew |date=9 March 2023 |url=https://www.infoworld.com/article/3689648/meet-the-zig-programming-language.html |title=Meet Zig: The modern alternative to C |website=InfoWorld.com}}
=Direct interaction with C=
Zig promotes a gradual approach to portability that combines new Zig code with existing C code. To do this, it aims to make interaction with existing C libraries as seamless as possible. Zig imports its own libraries with the {{code|@import}} directive, typically in this fashion:
const std = @import("std");
Zig code within that file can now call functions inside std, for instance:
std.debug.print("Hello, world!\n", .{});
To work with C code, one simply replaces the {{code|@import}} with {{code|@cImport}}:
const c = @cImport(@cInclude("soundio/soundio.h"));
The Zig code can now call functions in the soundio library as if they were native Zig code. As Zig uses new data types that are explicitly defined, unlike C’s more generic {{code|int}} and {{code|float}}, a small number of directives are used to move data between the C and Zig types, including {{code|@intCast}} and {{code|@ptrCast}}.
=Comptime=
By using the {{code|comptime}} keyword, the programmer can explicitly have Zig evaluate sections of code at compile time, as opposed to runtime. Being able to run code at compile time allows Zig to have the functionality of macros and conditional compilation without the need for a separate preprocessor language.{{cite AV media |url=https://www.youtube.com/watch?v=Gv2I7qTux7g |title=The Road to Zig 1.0 - Andrew Kelley |publisher=ChariotSolutions |via=YouTube |date=2019-05-09}}
During compile time, types become first-class citizens. This enables compile-time duck typing, and is how Zig implements generic types.
For instance, in Zig, a generic linked list type might be implemented using a function like:
fn LinkedList(comptime T: type) type;
This function takes in some type {{code|T}}, and returns a custom {{code|struct}} defining a linked list with that data type.
Compiler
Zig also includes a C and C++ compiler, and can be used with either or both languages by leveraging with the commands zig cc
and zig c++
,{{Cite web|url=https://ziglang.org/download/0.6.0/release-notes.html#zig-cc|title=0.6.0 Release Notes|website=Ziglang.org|access-date=2020-04-19}} providing many headers including the C standard library (libc) and C++ Standard Library (libcxx) for many different platforms. This allows Zig’s cc
and c++
sub-commands to act as cross compilers out of the box (similarly to Clang).{{Cite web|title='zig cc': a Powerful Drop-In Replacement for GCC/Clang - Andrew Kelley|url=https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html|access-date=2021-05-28|website=andrewkelley.me}}{{Cite web|title=Zig Makes Go Cross Compilation Just Work|url=https://dev.to/kristoff/zig-makes-go-cross-compilation-just-work-29ho|access-date=2021-05-28|website=DEV Community|date=24 January 2021 |language=en}}
Zig treats cross-compiling as a first-class use-case of the language. This means any Zig compiler can compile runnable binaries for any of its target platforms, of which there are dozens. These include not only widely-used modern systems like ARM and x86-64, but also PowerPC, SPARC, MIPS, RISC-V, LoongArch64 and even the IBM z/Architectures (S390). The toolchain can compile to any of these targets without installing additional software, all the needed support is in the basic system. The experimental support is also provided for less known platforms like AMD and Nvidia GPUs or PlayStation 4 and 5 (with various degree of support).
Cross-compilation is also available for variety of the operating systems (mostly desktop ones). Popular UNIX-like ones and Windows are officially supported (and documented), but (minimal) applications can and have been made for Android (with Android NDK) or iOS.
Zig uses LLVM (written in C++) as a backend for optimization. Since version 0.10 the Zig compiler is written in the Zig programming language, i.e., it is a self-hosting compiler. The self-hosted linker is tightly coupled with the self-hosted compiler.
The LLVM backend is the default for most targets, except for SPIR-V. Zig also supports their self-hosted backend which can be enabled by using -fno-llvm
.
Packages
Version 0.11.0 bundles an experimental package manager, but no official package repository is available. Instead a package is simply a URL that points to a compressed file, or a Git repository. Each package ideally includes a standard build.zig
file (that the Zig compiler uses by convention to compile the source code) and a build.zig.zon
file containing metadata with name and version of the package.
Examples
=Hello World=
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
= Generic linked list =
const std = @import("std");
const stdout = std.io.getStdOut().writer();
fn LinkedList(comptime T: type) type {
return struct {
const Self = @This();
pub const Node = struct {
next: ?*Node = null,
data: T,
};
first: ?*Node = null,
pub fn prepend(
list: *Self,
new_node: *Node,
) void {
new_node.next = list.first;
list.first = new_node;
}
pub fn format(
list: Self,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
out_stream: anytype,
) !void {
try out_stream.writeAll("( ");
var it = list.first;
while (it) |node| : (it = node.next) {
try std.fmt.formatType(
node.data,
fmt,
options,
out_stream,
1,
);
try out_stream.writeAll(" ");
}
try out_stream.writeAll(")");
}
};
}
pub fn main() !void {
const ListU32 = LinkedList(u32);
var list = ListU32{};
var node1 = ListU32.Node{ .data = 1 };
var node2 = ListU32.Node{ .data = 2 };
var node3 = ListU32.Node{ .data = 3 };
list.prepend(&node1);
list.prepend(&node2);
list.prepend(&node3);
try stdout.print("{}\n", .{list});
try stdout.print("{b}\n", .{list});
}
- Output
- :
( 3 2 1 )
( 11 10 1 )
= String repetition with allocator =
const std = @import("std");
fn repeat(
allocator: std.mem.Allocator,
original: []const u8,
times: usize,
) std.mem.Allocator.Error![]const u8 {
var buffer = try allocator.alloc(
u8,
original.len * times,
);
for (0..times) |i| {
std.mem.copyForwards(
u8,
buffer[(original.len * i)..],
original,
);
}
return buffer;
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
var arena = std.heap.ArenaAllocator.init(
std.heap.page_allocator,
);
defer arena.deinit();
const allocator = arena.allocator();
const original = "Hello ";
const repeated = try repeat(
allocator,
original,
3,
);
try stdout.print("{s}\n", .{repeated});
}
- Output
- :
Hello Hello Hello
History
The name “Zig” was reportedly chosen through a process involving a Python script that randomly combined letters, starting with the letter “Z” and followed by a vowel or “Y”, in order to generate four-letter words. Despite the intended length, “Zig”, a three-letter word, was ultimately selected from the various combinations produced by the script.{{cite web |url=https://gist.github.com/andrewrk/73742bf4b8ed795c85ce |title=origin of the zig programming language name. by @andrewrk |author=andrewrk |date=2024-03-13 |access-date=2024-03-13}}
The previous bootstrapping compiler, written in Zig and C++ using LLVM as a back-end,{{Cite web|url=https://www.gingerbill.org/article/2019/05/13/a-reply-to-the-road-to-zig/|title=A Reply to _The Road to Zig 1.0_|date=2019-05-13|website=www.gingerbill.org|language=en-gb|access-date=2020-02-11}}{{Cite web|title=ziglang/zig|date=2020-02-11|url=https://github.com/ziglang/zig|website=GitHub|publisher=Zig Programming Language|access-date=2020-02-11}} supporting many of its native targets,{{Cite web|url=https://ziglang.org/#Tier-System|title=The Zig Programming Language|website=Ziglang.org|access-date=2020-02-11}} was removed in version 0.11. Newer versions of Zig use a prebuilt WebAssembly version of Zig to bootstrap itself.
Projects
- Bun is a JavaScript and TypeScript runtime written in Zig, using Safari’s JavaScriptCore virtual machine.
- Ghostty{{Cite web |title=ghostty-org/ghostty |url= https://github.com/ghostty-org/ghostty |access-date=2024-12-27 |website=Github |language=en}} is a terminal emulator written in Zig.
- The TigerBeetle{{Cite web |title=tigerbeetle/tigerbeetle |url= https://github.com/tigerbeetle/tigerbeetle |access-date=2024-12-30 |website=Github |language=en}} financial transaction database is written in Zig.
- [https://github.com/Senryoku/Deecy Deecy], an up-and-coming (latest release as of this writing is version 0.3.0) emulator of Sega's Dreamcast home video gaming console platform, completely written in Zig from scratch.
- See a more comprehensive list of [https://linuxlock.org/blog/companies-using-zig/ companies and projects utilizing Zig in production].
See also
References
=Citations=
{{Reflist}}
=Bibliography=
- {{Cite web
|first=Jane |last=Elizabeth
|website=jaxenter
|date=2017-10-19
|title=Tired of C? New programming language Zig aims to be more pragmatic and readable
|url=https://jaxenter.com/replace-c-zig-language-138242.html
|archive-url=https://web.archive.org/web/20201001005039/https://jaxenter.com/replace-c-zig-language-138242.html
|archive-date=2020-10-01
|access-date=2020-04-22
}}
- {{Cite web
|url=https://www.infoworld.com/article/3113083/new-challenger-joins-rust-to-upend-c-language.html
|title=New challenger joins Rust to topple C language
|last=Yegulalp |first=Serdar
|date=2016-08-29
|website=InfoWorld
|language=en
|access-date=2020-02-11
}}
- {{Cite book
|last1=Owens|first1=Jeffery|date=2023-12-02
|title=Mastering Zig Programming
|publisher=Independently Published
|isbn=979-8870587332
|language=en
|ref=none
}}
- {{Cite book
|last1=Allen|first1=Corby|date=2024-06-20
|title=Zig Programming Mastery
|publisher=Independently Published
|isbn=979-8329021424
|language=en
|ref=none
}}
External links
- {{Official website|ziglang.org}}
- {{GitHub|ziglang|Zig}}
- [https://www.youtube.com/watch?v=Z4oYSByyRak Movie: Introducing Zig]
- [https://www.youtube.com/watch?v=Gv2I7qTux7g Movie: The Road to 1.0]
- [https://discu.eu/weekly/zig/ Zig Weekly]
{{Programming languages}}
{{Authority control}}
Category:High-level programming languages
Category:C (programming language) compilers
Category:Cross-platform software
Category:Cross-platform free software
Category:Free and open source compilers
Category:Free computer libraries
Category:Programming languages
Category:Programming languages created in 2015
Category:Software using the MIT license