Now we will write and run a complete Zig program.
Create a file named:
hello.zigPut this code inside it:
const std = @import("std");
pub fn main() void {
std.debug.print("Hello, Zig!\n", .{});
}This is a full Zig program. It is small, but it already shows the basic structure used by larger Zig programs.
Running the Program
Open a terminal in the same folder as hello.zig.
Run:
zig run hello.zigYou should see:
Hello, Zig!The command zig run does two things:
| Step | Meaning |
|---|---|
| Compile | Zig checks your code and turns it into a program |
| Run | Zig immediately executes that program |
This is useful while learning because you can edit a file, run one command, and see the result.
The Import Line
The first line is:
const std = @import("std");This loads Zig’s standard library.
The standard library contains common tools: printing, memory utilities, file handling, testing, formatting, data structures, and operating system support.
The name std is just a constant. We could technically choose another name, but Zig programmers almost always use std.
const standard_library = @import("std");This would work, but it is unusual. Use std.
The Main Function
The next important line is:
pub fn main() void {The word fn means function.
A function is a named block of code that can run.
The name main is special. In a normal executable program, Zig starts by calling main.
The word pub means public. For main, we write pub so the function is visible as the program entry point.
The word void means the function returns nothing.
So this line means:
Define a public function named main.
It takes no arguments.
It returns nothing.The body of the function is placed between braces:
{
std.debug.print("Hello, Zig!\n", .{});
}Everything inside these braces belongs to main.
Printing Text
The line inside main is:
std.debug.print("Hello, Zig!\n", .{});This prints text.
The first argument is the format string:
"Hello, Zig!\n"The \n means newline. It moves the cursor to the next line after printing.
The second argument is:
.{}This is an empty tuple-like value used for formatting arguments.
For now, read it as:
There are no extra values to insert into the string.Later, when we print variables, we will put values inside it.
For example:
const age = 10;
std.debug.print("Age: {}\n", .{age});The {} inside the string is a placeholder. The value age is inserted there.
Changing the Message
Try changing the program:
const std = @import("std");
pub fn main() void {
std.debug.print("I am learning Zig.\n", .{});
}Run it again:
zig run hello.zigYou should see:
I am learning Zig.This is the basic learning loop:
- edit the code
- run the code
- read the output
- fix mistakes
- run again
You will use this loop constantly.
A Program with a Variable
Now try this version:
const std = @import("std");
pub fn main() void {
const language = "Zig";
std.debug.print("Hello, {s}!\n", .{language});
}Output:
Hello, Zig!This line creates a constant:
const language = "Zig";A constant is a name for a value that cannot be changed after it is set.
The value is a string:
"Zig"Then this line prints it:
std.debug.print("Hello, {s}!\n", .{language});The {s} means “format this value as a string.”
The value language is passed in:
.{language}So Zig prints:
Hello, Zig!A Program with a Number
Now try a number:
const std = @import("std");
pub fn main() void {
const year = 2026;
std.debug.print("The year is {}.\n", .{year});
}Output:
The year is 2026.For numbers, plain {} is enough.
The important idea is that printing uses two parts:
| Part | Example | Meaning |
|---|---|---|
| Format string | "The year is {}.\n" | Text with placeholders |
| Arguments | .{year} | Values inserted into placeholders |
The number of placeholders should match the number of arguments.
Common Beginner Mistake: Missing Semicolon
Most Zig statements end with a semicolon.
This is correct:
const year = 2026;This is wrong:
const year = 2026If you forget the semicolon, Zig will show a compiler error.
At first, compiler errors may look intimidating. Read them slowly. Zig usually tells you the file, line number, and kind of problem.
Common Beginner Mistake: Wrong Format Placeholder
This is wrong:
const language = "Zig";
std.debug.print("Hello, {}!\n", .{language});For strings, use {s}:
const language = "Zig";
std.debug.print("Hello, {s}!\n", .{language});Zig’s formatting is strict. That is useful. It catches mistakes early instead of guessing what you meant.
Building Instead of Running
So far we used:
zig run hello.zigThis compiles and runs immediately.
You can also build an executable:
zig build-exe hello.zigOn Linux and macOS, this creates:
helloRun it with:
./helloOn Windows, this creates:
hello.exeRun it with:
.\hello.exeThe difference is:
| Command | Result |
|---|---|
zig run hello.zig | Compile and run now |
zig build-exe hello.zig | Compile and keep the executable |
For small examples, use zig run.
For programs you want to keep, use zig build-exe or later zig build.
What You Have Learned
You have now written a complete Zig program.
You saw how to import the standard library, define main, print text, use a constant, format a string, and run a source file.
This small program is the seed of every larger Zig program. Larger programs have more functions, more files, more types, and more logic, but they still begin with the same basic idea: source code is checked by the compiler, then turned into a program the computer can run.