[Setup] Zig Development Environment
Zig is a systems programming language designed as an alternative to C. It features a simple syntax, elimination of hidden control flow, and compile-time safety checks, making it well-suited for embedded systems, game development, and high-performance applications. This page covers how to install the Zig development environment and how to compile and run a program.
Syntax
// -----------------------------------------------
// zig run — compiles and runs a source file directly
// -----------------------------------------------
zig run filename.zig
// filename.zig : path to the Zig source file you want to run
// -----------------------------------------------
// zig build-exe — builds an executable binary
// -----------------------------------------------
zig build-exe filename.zig
// a native executable is generated in the same directory
// -----------------------------------------------
// minimal Zig program structure
// -----------------------------------------------
const std = @import("std"); // imports the standard library
pub fn main() !void { // entry point. !void indicates the function may return an error
// write to standard output
const stdout = std.io.getStdOut().writer();
try stdout.print("text\n", .{});
}
Syntax reference
| Syntax / Command | Description |
|---|---|
zig run file.zig | Compiles and immediately runs a source file. Useful for checking behavior during development. |
zig build-exe file.zig | Produces an executable binary from a source file. The output file name matches the source file name by default. |
zig build-lib file.zig | Produces a library (static or shared) from a source file. |
zig test file.zig | Runs all test blocks defined in the source file. |
zig version | Displays the installed Zig version. |
zig fmt file.zig | Automatically formats a source file according to the official Zig style. |
@import("std") | Imports the standard library. The conventional form is const std = @import("std");. |
pub fn main() !void | Defines the program entry point. ! indicates an error union return type. |
try expression | Propagates an error to the caller if the expression returns one. |
std.io.getStdOut().writer() | Returns a Writer for standard output. |
Installation
| Method | Command / Steps | OS |
|---|---|---|
| Download from official site | Download a prebuilt binary from ziglang.org/download/ and add it to your PATH. | Windows / macOS / Linux |
| Homebrew (macOS / Linux) | brew install zig | macOS / Linux |
| apt (Debian / Ubuntu) | sudo apt install zig (if the version is outdated, the official binary is recommended) | Linux |
| Snap (Ubuntu) | sudo snap install zig --classic --beta | Linux |
| winget (Windows) | winget install zig.zig | Windows |
| mise (version manager) | mise use zig@latest (supports switching between multiple versions) | macOS / Linux |
Sample code
hello.zig
// hello.zig — a Hello World sample in Zig
// demonstrates printing strings to standard output
// and the basic program structure
// import the standard library
// @import() is a built-in function executed at compile time
const std = @import("std");
// pub fn main() !void is the program entry point
// !void means "returns void on success, or an error value on failure"
pub fn main() !void {
// get a Writer for standard output
const stdout = std.io.getStdOut().writer();
// define some string constants
// const declares an immutable binding
const name1 = "Alice";
const name2 = "Bob";
const name3 = "Carol";
const name4 = "Dave";
const name5 = "Eve";
// try propagates an error to the caller if the function returns one
// the second argument to print() is a tuple of format arguments (pass .{} for none)
try stdout.print("=== Participant List ===\n", .{});
try stdout.print("\n", .{});
// use {} placeholders to embed values in the output
try stdout.print("Name: {s}\n", .{name1});
try stdout.print("Name: {s}\n", .{name2});
try stdout.print("Name: {s}\n", .{name3});
try stdout.print("Name: {s}\n", .{name4});
try stdout.print("Name: {s}\n", .{name5});
try stdout.print("\n", .{});
// format output combining integers and strings
// {d} displays an integer in decimal
const scores = [_]u32{ 95, 87, 92, 78, 88 };
const names = [_][]const u8{ name1, name2, name3, name4, name5 };
try stdout.print("--- Score List ---\n", .{});
// iterate over arrays with a for loop
// use |value, index| to get both the value and index at the same time
for (names, scores) |name, score| {
try stdout.print(" {s}: {d}\n", .{ name, score });
}
try stdout.print("\nZig setup complete!\n", .{});
}
zig run hello.zig === Participant List === Name: Alice Name: Bob Name: Carol Name: Dave Name: Eve --- Score List --- Alice: 95 Bob: 87 Carol: 92 Dave: 78 Eve: 88 Zig setup complete!
Notes
The most reliable way to install Zig is to download a prebuilt binary for your OS from the official site (ziglang.org) and add it to your PATH. On macOS and Linux, brew install zig is also a convenient option. After installation, run zig version to confirm the version and verify that your environment is set up correctly. You can run a program directly with zig run filename.zig. To produce a production binary, use zig build-exe. The entry point is defined as pub fn main() !void, and you write to standard output using the print() method on a Writer obtained from std.io.getStdOut().writer(). The try keyword propagates errors to the caller and is the foundation of error handling in Zig. For more on basic syntax, see Variables and Constants. For more on error handling, see Error Handling.
If you find any errors or copyright issues, please contact us.