Skip to content

Understanding `zig build-exe`

In the previous section, we used this command:

Understanding zig build-exe

In the previous section, we used this command:

zig run hello.zig

That command compiles your Zig file and runs it immediately.

Now we will look at a different command:

zig build-exe hello.zig

This command compiles your Zig file and creates an executable file.

An executable file is a program you can run directly from your operating system.

Source File and Executable File

Start with this file:

hello.zig

Inside it, write:

const std = @import("std");

pub fn main() void {
    std.debug.print("Hello, executable!\n", .{});
}

Now run:

zig build-exe hello.zig

Zig reads hello.zig, checks the code, compiles it, links it, and creates an executable.

On Linux and macOS, the result is usually:

hello

You run it with:

./hello

On Windows, the result is usually:

hello.exe

You run it with:

.\hello.exe

The source file is the text you write.

The executable file is the program Zig creates.

What build-exe Means

The command has two parts:

zig build-exe hello.zig

The first part is:

zig

This runs the Zig tool.

The second part is:

build-exe

This tells Zig what kind of output you want.

The third part is:

hello.zig

This is the input file.

So the command means:

Use Zig to build an executable from hello.zig.

Compile and Link

When you run zig build-exe, Zig does more than one thing.

First, it compiles your Zig code. Compilation checks the source code and turns it into lower-level machine instructions.

Second, it links the program. Linking connects your code with the pieces it needs from libraries and the operating system.

For a small program, this feels like one step. Internally, it has several stages.

You do not need to understand every stage yet. For now, remember this:

Source code goes in.
Executable program comes out.

zig run vs zig build-exe

Both commands compile code, but they are used for different situations.

CommandWhat it doesWhen to use it
zig run hello.zigCompile and run immediatelyQuick experiments
zig build-exe hello.zigCompile and save executableCreating a program file

When learning, zig run is convenient.

When you want a real output file, use zig build-exe.

Running the Executable

After building, you run the executable directly.

On Linux and macOS:

./hello

The ./ means “run the file named hello in the current directory.”

This is needed because most Unix-like shells do not automatically search the current directory for programs.

On Windows PowerShell:

.\hello.exe

The .\ means the same idea: run the file in the current directory.

Choosing an Output Name

By default, Zig uses the source file name.

If the input is:

hello.zig

the output is usually:

hello

or:

hello.exe

You can choose a different output name with -femit-bin.

zig build-exe hello.zig -femit-bin=myprogram

Now the output is named:

myprogram

On Windows, you may choose:

zig build-exe hello.zig -femit-bin=myprogram.exe

This is useful when the file name and program name should be different.

Build Modes

Zig can build the same program in different modes.

A build mode controls safety checks, optimization, and debugging information.

The most common modes are:

ModePurpose
DebugBest for development and learning
ReleaseSafeOptimized, but keeps many safety checks
ReleaseFastOptimized for speed
ReleaseSmallOptimized for small binary size

By default, Zig builds in debug mode.

Debug mode is best while learning because it keeps helpful checks and better debugging information.

To build in release-fast mode:

zig build-exe hello.zig -O ReleaseFast

To build in release-safe mode:

zig build-exe hello.zig -O ReleaseSafe

To build in release-small mode:

zig build-exe hello.zig -O ReleaseSmall

For now, use the default mode unless you have a reason to change it.

What Debug Mode Gives You

Debug mode is slower than release mode, but it is better for learning.

It helps catch mistakes such as:

MistakeExample
Integer overflowA number becomes too large for its type
Invalid array accessCode reads outside an array
Reaching impossible codeCode reaches unreachable
Better stack tracesError messages are easier to inspect

Speed matters later. Correctness matters first.

Use debug builds while writing and testing code.

A Simple Error Example

Try this program:

const std = @import("std");

pub fn main() void {
    const items = [_]u8{ 1, 2, 3 };
    std.debug.print("{}\n", .{items[10]});
}

Build and run it:

zig build-exe hello.zig
./hello

The array has only three elements, but the program tries to access index 10.

In debug mode, Zig can catch this kind of error instead of silently continuing with invalid memory.

This is one reason debug builds are useful.

Cross Compilation Preview

One powerful feature of zig build-exe is cross compilation.

Cross compilation means building a program for a different platform.

For example, on one machine you can ask Zig to build for Linux:

zig build-exe hello.zig -target x86_64-linux

Or for Windows:

zig build-exe hello.zig -target x86_64-windows

Or for macOS on Apple Silicon:

zig build-exe hello.zig -target aarch64-macos

You do not need to master this now. The important idea is that Zig treats cross compilation as a normal compiler feature, not an advanced trick.

Common Beginner Problems

If you run:

zig build-exe hello.zig

and see an error like:

error: file not found

make sure your terminal is in the same directory as hello.zig.

You can list files in the current directory.

On macOS and Linux:

ls

On Windows PowerShell:

dir

If you build successfully but cannot run the program, check the file name.

On Linux and macOS, use:

./hello

On Windows, use:

.\hello.exe

If you type only:

hello

on Linux or macOS, the shell may not find it. Use ./hello.

Mental Model

zig build-exe is the direct way to turn one Zig source file into one executable program.

You give Zig a .zig file.

Zig gives you a program file.

That is the basic build path:

hello.zig -> compiler -> hello

Later, when projects become larger, we will use zig build and a build.zig file. But zig build-exe is the simplest place to start because it shows the core idea without extra project structure.