Preply — Study more efficiently by working with a personal tutor. Get 50% off.Affiliate

Wikipedia

Zig (programming language)

Zig (programming language)

Zig is a system programming language designed to be a general-purpose improvement to the C programming language. It is free and open-source software, released under an MIT License on Codeberg, a source-code sharing platform. Differences with C relate to control flow, function calls, library imports, variable declaration and Unicode support. 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 reflection. Zig requires manual memory management. Features for low-level programming include packed structs, arbitrary-width integers and multiple pointer types. Zig was designed by Andrew Kelley and first announced in 2016. Development is funded by the Zig Software Foundation (ZSF) which receives corporate sponsorships as well as personal donations.

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, its goal is to be a language designed for "robustness, optimality and maintainability". The small and simple syntax is an important part of that maintainability, as one of the language's goals is to allow maintainers to debug code written in Zig without having to learn the intricacies of a language they might not be familiar with. 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. Error handling is handled through error types and can be handled with catch or try. Generics are achieved through compile time code generation and accommodating a form of duck typing with the comptime directive.

Memory handling Memory allocation in the Zig standard library follows the convention that allocation is handled through structs 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:

In the code, the function would examine the size of original and then malloc 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:

In this code, the allocator variable is passed a struct that describes what code should perform the allocation, and the repeat function returns either the resulting string or, using the optional type as indicated by the !, 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. 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 countTheNumberOfUsers that returns an integer, and an integer variable, theCountedUsers that holds the result. In many languages, a magic number would be placed in theCountedUsers to indicate that countTheNumberOfUsers has not yet been called, while many implementations would just set it to zero. In Zig, this could be implemented as an var theCountedUsers: ?i32 = null 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 defer, which marks some code to be performed at the end of a scope 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 free to ensure it is released no matter what happens. The Zig standard library avoids hidden allocations. Allocation is not managed in the language directly. Instead, heap access is done via the standard library, explicitly.

Direct interaction with C Zig promotes a gradual approach to portability by providing direct interoperability of Zig code with C code, allowing code from one language to call code from the other. Since 0.16.0, this is implemented through Zig's build system, by enabling C libraries to be defined within the build.zig file of the Zig project, to enable for the Zig code to import the C libraries through the use of the @import keyword. For inclusion of C code in a primarily Zig project, this is typically implemented in the build.zig file, in a similar fashion to the following example (note that this example is only of the relevant code):

The C headers can then be called in Zig code with the following code:

This is in line with how Zig imports its own libraries, similarly with the @import directive, typically in this fashion:

For the alternate method of utilising and calling Zig code inside a primarily C program, this is more difficult than the aforementioned, as the Zig build system focusses on a Zig-based environment. However, it is a similar setup, as the Zig build system is still utilised for such a purpose in most scenarios. As C code naturally uses C header files (.h) and macros, all Zig declarations, such as functions, would need to be expressed either within header files or extern declarations, as would be done for C interoperability with programming languages other than Zig. The following code is an example for a C project which uses Zig code, where the shared declarations between C and Zig code are contained within an extern.h file:

Zig 0.16.0 deprecated @cImport, going forward C Translation will be handled via the Build System instead of using the @cImport language builtin, which has been 'deleted' from the language. Additionally the release deprecated std.Build.Step.TranslateC in favour using an explicit package dependency of the official translate-c package, which is the same implementation as the previous build step version with additional configuration options. Prior to 0.16.0, the system used for C interoperability did not use the Zig build system, and instead used a @cImport directive only used for calling C code. This directive would often wrap an additional @cInclude directive, which mirrored the #include macro that would be seen within C code. In these prior versions of Zig, C libraries are imported in the following manner:

This Zig code would be functionally equivalent to the following C code with the main difference being that the library is accessed through calls to the constant identifier c, as seen in the current 0.16.0 example.

The Zig code would then be able to call functions from soundio library in the same manner as calling functions from other Zig code, As Zig uses new data types that are explicitly defined, unlike C’s more generic int and float, a small number of directives are used to move data between the C and Zig types, including @intCast and @ptrCast. This is notably different from the current implementations, as Zig code would directly be able to import code from system header files, whereas the current implementation only allows for Zig code to import C code from local libraries defined within the users code.

Compile time evaluation Zig can evaluate sections of code at compile time instead of runtime using the comptime keyword. Running code at compile time provides functionality similar to macros and conditional compilation, without the use of a separate preprocessor language. Types become first-class citizens at compile time, allowing compile-time duck typing, which Zig uses to implement generic types. The example below declares a generic linked list:

The function takes the type T and produces a concrete linked-list type based on T.

Compiler The Zig compiler is self-hosted, meaning it is written in the Zig programming language. Prior to version 0.10 Zig was compiled using LLVM based 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++, 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). 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. The LLVM backend is the default for most targets, except for SPIR-V, and x86-64 (although this is currently just in Debug mode). Zig also supports their self-hosted backend which can be enabled by using -fno-llvm.

History Kelley began to develop a digital audio workstation, but he found "Go interoperability with C libraries difficult, and found the garbage collector caused audio delays. He tried C++, but found that small mistakes led to memory corruption bugs that took weeks to fix. He tried Rust but "really struggled to write code that would satisfy Rust's rules," and spent a month trying to make font rendering work." The name Zig was picked using a script that generated random combinations of letters starting with the letter z. The previous bootstrapping compiler, written in Zig and C++ using LLVM as a back-end, supporting many of its native targets, was removed in version 0.11. Newer versions of Zig use a prebuilt WebAssembly version of Zig to bootstrap itself. On 26 November 2025, Zig development migrated from GitHub to Codeberg, citing GitHub's declining reliability under Microsoft ownership, particularly due to poor use of Generative AI on the platform, as a primary reason for this change. One cited example of the platform's declining reliability was the apparent unreliability and delays towards the fixing of bugs in GitHub's CI platform, GitHub Actions. In addition, the Zig development team had concerns with the Generative AI direction of GitHub, which was in contrast to the Zig project's policy against Generative AI. In 2026, Codeberg would introduce a policy against Generative AI, similar to the policy of the Zig project.

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

Notable projects Projects that use (or have previously used) Zig include:

Bun, a JavaScript and TypeScript runtime originally written in Zig (until v1.3.14) and rewritten in Rust (starting with v1.4.0) in 2026, using Safari's JavaScriptCore virtual machine. TigerBeetle, a financial transaction database Ghostty, a GPU accelerated terminal emulator

References

Citations

Bibliography Elizabeth, Jane (19 October 2017). "Tired of C? New programming language Zig aims to be more pragmatic and readable". jaxenter. Archived from the original on 1 October 2020. Retrieved 22 April 2020. Yegulalp, Serdar (29 August 2016). "New challenger joins Rust to topple C language". InfoWorld. Retrieved 11 February 2020.

External links Official website Zig on Codeberg

Tags

  • C (programming language) compilers
  • Compiled programming languages
  • Cross-platform free software
  • Cross-platform software
  • Embedded systems
  • Free and open source compilers
  • Free computer libraries
  • High-level programming languages
  • Programming languages
  • Programming languages created in 2015
  • Software using the MIT license
  • Statically typed programming languages