The first program in Zig is small.
const std = @import("std");
pub fn main() void {
std.debug.print("hello, zig\n", .{});
}Save this in a file named main.zig.
Run it:
zig run main.zigThe output is:
hello, zigA Zig program is made of declarations. The first line declares a name:
const std = @import("std");const means the name cannot be changed after it is set. Here the name is std. The value comes from @import("std"), which imports Zig’s standard library.
The next declaration is a function:
pub fn main() void {
...
}fn begins a function declaration. The function is named main. This is where the program starts.
pub makes the function visible outside the file. For an executable program, main must be visible to the compiler.
The word after the parameter list is the return type:
voidvoid means the function returns no value.
The body of the function is inside braces:
{
std.debug.print("hello, zig\n", .{});
}This calls std.debug.print.
The first argument is a string:
"hello, zig\n"The \n means newline.
The second argument is:
.{}std.debug.print uses this second argument for values that should be inserted into the string. There are no inserted values in this example, so the argument is an empty tuple.
A slightly larger version prints a number:
const std = @import("std");
pub fn main() void {
const year = 2026;
std.debug.print("Zig in {d}\n", .{year});
}The output is:
Zig in 2026The {d} in the string says: print a decimal integer. The value comes from the tuple:
.{year}Zig does not hide much here. A name is declared. A function is called. The format string says what to print. The values to print are passed explicitly.
This is the usual shape of a small Zig program:
const std = @import("std");
pub fn main() void {
// work goes here
}Exercise 1-1. Run the first program.
Exercise 1-2. Change the message.
Exercise 1-3. Print two lines.
Exercise 1-4. Declare a constant named name and print it with {s}.