zig-0.16
Up-to-date Zig 0.16.0 language and standard library skill. Use when writing, reviewing, debugging, or migrating Zig code, working with build.zig/build.zig.zon, std modules, comptime, C interop, and modern 0.16 APIs.
Up-to-date Zig 0.16.0 language and standard library skill. Use when writing, reviewing, debugging, or migrating Zig code, working with build.zig/build.zig.zon, std modules, comptime, C interop, and modern 0.16 APIs.
This skill covers the Zig 0.16.0 language and standard library. Use it when writing, reviewing, or migrating Zig code, working with build.zig / build.zig.zon, standard library modules, and comptime metaprogramming.
Zig evolves rapidly. Training data, blog posts, and many public examples are stale. This skill is the main Zig 0.16.0 aggregate skill for this repository: it condenses the official 0.16.0 language reference, the official std index, the Chinese Zig homepage, and the local offline reference set under references/.
zig version)Use this skill when the user needs to write, review, debug, or migrate Zig 0.16.0 code, or when working with build.zig / build.zig.zon, std modules, comptime, or C interop.
This skill does not collect, store, or transmit any user data. All code examples are for local development reference only.
From the Zig 0.16.0 docs and Chinese homepage, Zig is a general-purpose programming language and toolchain for building robust, optimal, and reusable software.
comptime makes type-driven programming and code generation first-class.Example invocations:
Write an HTTP server in Zig 0.16 using std.http
Create a build.zig that depends on a third-party library
Review this Zig code for 0.16 compatibility issues
Migrate this Zig 0.14 project to 0.16
Step 1. Confirm version — Run zig version to verify the user is on 0.16.0
Step 2. Review official reference — Read the main skill body for the overall framework
Step 3. Look up std modules — Find the relevant module from the std index, then load the matching references/ file
Step 4. Use examples — Load copyable code snippets from examples/
Step 5. Handle migrations — For legacy code, check the Removed Features and Breaking Changes sections
references/*.md when you need concrete examples or offline guidance.zig-raylib or zig-sdl3-bindings only for those library-specific workflows.The official Zig 0.16.0 language reference covers these major areas:
test declarations, doctests, leak reporting, test output, and std.testing.struct, enum, union, opaque, tuples, anonymous literals, non-exhaustive enums, tagged unions, and result location semantics.switch, while, for, if, defer, errdefer, unreachable, and noreturn.comptime, generic data structures, builtin functions, atomics, async-related syntax history, and assembly.@cImport, @cInclude, @extern, and @export.The official 0.16.0 std index exposes the modules most often needed for application work:
std.Build, std.zig, std.zonstd.Io, std.fs, std.process, std.os, std.cstd.heap, std.mem, std.fmt, std.ascii, std.unicode, std.base64std.http, std.json, std.Uri, std.netstd.log, std.debug, std.testing, std.time, std.Tzstd.math, std.hash, std.crypto, std.Random, std.sort, std.simdstd.Thread, std.atomic, std.metastd.ArrayList, std.HashMap, std.ArrayHashMap, std.MultiArrayList, std.StaticStringMap, std.bit_set, std.PriorityQueueUse the official std index to confirm module names and the local references/ folder for curated examples and practical notes.
usingnamespace - removed// WRONG
pub usingnamespace @import("other.zig");
// CORRECT
const other = @import("other.zig");
pub const foo = other.foo;
async/await - removedThese keywords are still not part of normal Zig 0.16 source code patterns. Do not suggest legacy async examples from old posts.
@fence - removedUse stronger atomic orderings or RMW operations instead.
The std.io era patterns remain stale. Modern Zig uses std.Io.Writer and std.Io.Reader with explicit buffers and interface access.
// WRONG - old API
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello\n", .{});
// CORRECT - modern API
var buf: [4096]u8 = undefined;
var stdout_writer = std.fs.File.stdout().writer(&buf);
const stdout = &stdout_writer.interface;
try stdout.print("Hello\n", .{});
try stdout.flush();
var buf: [4096]u8 = undefined;
var file_reader = file.reader(&buf);
const r = &file_reader.interface;
while (try r.takeDelimiter('\n')) |line| {
// line does not include '\n'
}
var out_buf: [256]u8 = undefined;
var w: std.Io.Writer = .fixed(&out_buf);
try w.print("Hello {s}", .{"world"});
const result = w.buffered();
var r: std.Io.Reader = .fixed("hello\nworld");
const first = (try r.takeDelimiter('\n')).?;
_ = first;
Deprecated names such as BufferedWriter, GenericWriter, AnyWriter, and FixedBufferStream should not be suggested for Zig 0.16 code.
The official 0.16.0 docs describe the Zig Build System as a cross-platform, dependency-free way to declare project build logic in build.zig.
zig init or scaffold the project manually.zig build --help.build.zig.zon.std.Build and module-based APIs in build.zig.const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "app",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
}),
});
b.installArtifact(exe);
}
root_module is mandatory// WRONG - removed field on addExecutable/addLibrary/addTest
b.addExecutable(.{
.name = "app",
.root_source_file = b.path("src/main.zig"),
});
// CORRECT
b.addExecutable(.{
.name = "app",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
}),
});
// WRONG
exe.addModule("helper", helper_mod);
// CORRECT
exe.root_module.addImport("helper", helper_mod);
const dep = b.dependency("lib", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("lib", dep.module("lib"));
Compile-level methods like exe.linkSystemLibrary() and exe.addCSourceFiles() should generally move to exe.root_module.* based APIs in modern code.
Never suggest .{} for container initialization unless the type is documented to support it. For the common std containers and allocators, Zig 0.16 still expects .empty or .init.
// WRONG
var list: std.ArrayList(u32) = .{};
var gpa: std.heap.DebugAllocator(.{}) = .{};
// CORRECT
var list: std.ArrayList(u32) = .empty;
var map: std.AutoHashMapUnmanaged(u32, u32) = .empty;
var gpa: std.heap.DebugAllocator(.{}) = .init;
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
std.ArrayListUnmanaged -> std.ArrayListstd.heap.GeneralPurposeAllocator -> std.heap.DebugAllocatorstd.BoundedArray replacementvar buffer: [8]i32 = undefined;
var stack = std.ArrayList(i32).initBuffer(&buffer);
Some custom formatters now require {f}:
// WRONG
std.debug.print("{}", .{std.zig.fmtId("x")});
// CORRECT
std.debug.print("{f}", .{std.zig.fmtId("x")});
Modern format methods also use writer-based signatures:
pub fn format(self: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void {
_ = self;
_ = writer;
}
zig version to confirm the compiler is 0.16.0.zig build
zig build run
zig test src/main.zig
zig build test
const std = @import("std");
const parseInt = std.fmt.parseInt;
test "parse integers" {
const input = "123 67 89,99";
const gpa = std.testing.allocator;
var list: std.ArrayList(u32) = .empty;
defer list.deinit(gpa);
var it = std.mem.tokenizeAny(u8, input, " ,");
while (it.next()) |num| {
const n = try parseInt(u32, num, 10);
try list.append(gpa, n);
}
const expected = [_]u32{ 123, 67, 89, 99 };
for (expected, list.items) |exp, actual| {
try std.testing.expectEqual(exp, actual);
}
}
These patterns are still useful for 0.16 review and migration work:
@branchHint replaces @setCold// WRONG
@setCold(true);
// CORRECT
@branchHint(.cold);
@export takes a pointer// WRONG
@export(foo, .{ .name = "bar" });
// CORRECT
@export(&foo, .{ .name = "bar" });
// WRONG
: "rcx", "r11"
// CORRECT
: .{ .rcx = true, .r11 = true }
const S = struct {
x: u32,
const default: S = .{ .x = 0 };
fn init(v: u32) S { return .{ .x = v }; }
};
const a: S = .default;
const b: S = .init(42);
state: switch (initial) {
.idle => continue :state .running,
.running => if (done) break :state result else continue :state .running,
.error => return error.Failed,
}
switch (value) {
.a, .b => {},
else => {}, // other named tags
_ => {}, // unnamed integer values
}
| Error | Fix |
|-------|-----|
| no field 'root_source_file' | Use root_module = b.createModule(.{...}) in addExecutable/addLibrary/addTest |
| use of undefined value | Arithmetic on undefined is illegal; initialize data before use |
| type 'f32' cannot represent integer | Use a float literal such as 123_456_789.0 |
| std.io examples don't compile | Use std.Io writer/reader patterns with explicit buffers |
| Old container init example uses .{} | Prefer .empty or .init depending on the type |
| ambiguous format string | Use {f} for custom formatter output |
| sanitize_c = true no longer works | Use the modern enum-style sanitize configuration from recent Zig releases |
| std.fifo.LinearFifo examples fail | Prefer std.Io.Reader or std.Io.Writer based streaming patterns |
| posix.sendfile examples fail | Use file writer APIs such as .sendFileAll() |
| std.fmt.Formatter examples fail | Use std.fmt.Alt in modern code |
| fmtSliceEscapeLower/fmtSliceEscapeUpper missing | Use std.ascii.hexEscape(bytes, .lower/.upper) |
| User's zig version is not 0.16.0 | Confirm version, then guide to upgrade or switch skills |
| User asks about raylib/SDL3 API | Guide to use zig-raylib / zig-sdl3-bindings |
| Code from old blog/tutorial with unknown version | Use Quick Fixes table to check each compilation error pattern |
| Need module-specific details | Load the matching local references/*.md file |
| Build-system API uncertainty | Check both local std-build.md and the official build-system docs |
Use the local examples/ directory when you need copyable snippets quickly or cannot rely on live web access:
examples/quickstart-workflows.md - starter project, tests, JSON, process, HTTP, review checklistexamples/build-zig-zon-workflows.md - package metadata, dependencies, executable and library layoutsexamples/comptime-patterns.md - reflection, generic helpers, generated types, inline loopsexamples/c-interop-workflows.md - @cImport, exported APIs, static libraries, headersexamples/std-thread-patterns.md - spawn and join, mutex, wait group, atomic counter patternsUse docs/official/ when you need offline distilled versions of the official Zig 0.16 pages themselves rather than topic cards:
docs/official/official-sources.md - source index and navigationdocs/official/official-language-reference-0.16.md - language reference coverage mapdocs/official/official-introduction-0.16.md - introduction distillationdocs/official/official-std-index-0.16.md - standard library index distillationdocs/official/official-zh-cn-home-0.16.md - Chinese homepage distillationLoad these references when working with core language features:
zig fmt@ built-ins: casts, arithmetic, bit ops, memory, atomics, introspection, SIMD, C interopLoad these references when working with specific modules:
{f} notes| User Type | Usage | |-----------|-------| | Zig beginners | Write basic code and learn 0.16 API patterns | | Migration users | Migrate from older versions by following the Critical sections | | Experienced developers | Deep-dive into std modules via references/ and copy patterns from examples/ |
Customization options:
zig version is 0.16.0 before giving advice; API differences cause compilation errorsaddExecutable/addLibrary no longer accept root_source_file; use root_module = b.createModule(...)std.io patterns (e.g. std.io.getStdOut().writer()) do not compile under 0.16.0.{ } — ArrayList/HashMap must use .empty or .init{f} — Custom formatter output requires {f} instead of {}references/ local files over web search to ensure 0.16.0 consistencyQ: How does this skill differ from zig-0.15?
A: zig-0.16 is the primary skill covering the latest stable 0.16.0 release. zig-0.15 is retained as a legacy compatibility reference.
Q: What if example code fails to compile?
A: Verify zig version outputs 0.16.0. If the version differs, some APIs may have changed. Use the Quick Fixes table to diagnose.
Q: How do I find a specific std module?
A: Look up the module name in the Standard Library References section, then load the matching references/*.md file.
Q: Can I use this offline? A: Yes. All references/ and examples/ files are local copies and work without internet access.
Q: Does this skill collect my code? A: No. This skill is a pure documentation reference and does not collect any user data.
build.zig.zon and configs