Hello World in Zig 0.16

Zig 0.16 is nearly here (as of early April 2026, the 0.16.0 milestone is 97–99% complete on Codeberg (https://codeberg.org/ziglang/zig/milestone/32343), with a stable release expected in the coming weeks). This release represents one of the most significant architectural shifts in the language since the early days: a complete overhaul of I/O handling centered around the new std.Io interface.

The three “Hello World!” examples you shared perfectly illustrate the transition. Let’s break them down and explore what they reveal about Zig 0.16’s direction.

The Three Faces of “Hello World!” in Zig 0.16 Link to heading

Version 1 (Simple streaming write):

const std = @import("std");

pub fn main(init: std.process.Init) !void {
    try std.Io.File.stdout().writeStreamingAll(
        init.io,
        "Hello World!\n",
    );
}

This is the new minimal, unbuffered path. Notice the main() signature now takes std.process.Init (or a .Minimal variant). This main() injects essential runtime context—including the io handle—directly into your entry point. No more global std.os.argv or std.os.environ; everything is explicit and safer.

Version 2 (The familiar debug-style print):

const std = @import("std");

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

This still works for quick scripts and debugging. std.debug.print remains a convenient shortcut that does not require the full Io machinery.

Version 3 (Explicit buffered writer):

const std = @import("std");

pub fn main(init: std.process.Init) !void {
    var buffer: [4096]u8 = undefined;
    var stdout_impl = std.Io.File.stdout().writer(init.io, &buffer);
    const stdout = &stdout_impl.interface;

    try stdout.print("Hello {s}!\n", .{"Buffered World"});
    try stdout.print("Writing number: {d}\n", .{42});
    try stdout.flush();
}

Here we see the full power (and responsibility) of the new system: you allocate your own buffer in userspace, create a writer tied to the Io instance, obtain the generic Writer interface, perform formatted output and flush() when needed.

Happy coding in Zig!