Zig Language Reference (v0.15.2)
Zig evolves rapidly. Training data contains outdated patterns that cause compilation errors. This skill documents breaking changes and correct modern patterns.
Critical: Removed Features (0.15.x)
usingnamespace
- REMOVED
// WRONG - compile error pub usingnamespace @import("other.zig");
// CORRECT - explicit re-export const other = @import("other.zig"); pub const foo = other.foo;
async /await
- REMOVED
Keywords removed from language. Async I/O is now in std.Io interface.
Critical: I/O API Rewrite ("Writergate")
The entire std.io API changed. New std.Io.Writer and std.Io.Reader are non-generic with buffer in the interface.
Writing
// WRONG - old API const stdout = std.io.getStdOut().writer(); try stdout.print("Hello\n", .{});
// CORRECT - new API: provide buffer, access .interface, flush 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(); // REQUIRED!
Reading
// Reading from file var buf: [4096]u8 = undefined; var file_reader = file.reader(&buf); const r = &file_reader.interface;
// Read line by line (takeDelimiter returns null at EOF) while (try r.takeDelimiter('\n')) |line| { // process line (doesn't include '\n') }
// Read binary data const header = try r.takeStruct(Header, .little); const value = try r.takeInt(u32, .big);
Fixed Buffer Writer (no file)
var buf: [256]u8 = undefined; var w: std.io.Writer = .fixed(&buf); try w.print("Hello {s}", .{"world"}); const result = w.buffered(); // "Hello world"
Fixed Reader (from slice)
var r: std.io.Reader = .fixed("hello\nworld"); const line = try r.takeDelimiter('\n'); // "hello"
Removed: BufferedWriter , CountingWriter , std.io.bufferedWriter()
Deprecated: GenericWriter , GenericReader , AnyWriter , AnyReader , FixedBufferStream
New: std.Io.Writer , std.Io.Reader
- non-generic, buffer in interface
Replacements:
-
CountingWriter → std.Io.Writer.Discarding (has .fullCount() )
-
BufferedWriter → buffer provided to .writer(&buf) call
-
Allocating output → std.Io.Writer.Allocating
Critical: Build System (0.15.x)
root_source_file is REMOVED from addExecutable /addLibrary /addTest . Use root_module :
// WRONG - removed field b.addExecutable(.{ .name = "app", .root_source_file = b.path("src/main.zig"), // ERROR .target = target, });
// CORRECT b.addExecutable(.{ .name = "app", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }), });
Module imports changed:
// WRONG (old API) exe.addModule("helper", helper_mod);
// CORRECT exe.root_module.addImport("helper", helper_mod);
Adding dependency modules:
const dep = b.dependency("lib", .{ .target = target, .optimize = optimize }); exe.root_module.addImport("lib", dep.module("lib"));
See std.Build reference for complete build system documentation.
Critical: Container Initialization
Never use .{} for containers. Use .empty or .init :
// WRONG - deprecated var list: std.ArrayList(u32) = .{}; var gpa: std.heap.DebugAllocator(.{}) = .{};
// CORRECT - use .empty for empty collections var list: std.ArrayList(u32) = .empty; var map: std.AutoHashMapUnmanaged(u32, u32) = .empty;
// CORRECT - use .init for stateful types with internal config var gpa: std.heap.DebugAllocator(.{}) = .init; var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
Naming Changes
-
std.ArrayListUnmanaged → std.ArrayList (Unmanaged is now default, old name deprecated)
-
std.heap.GeneralPurposeAllocator → std.heap.DebugAllocator (GPA alias still works)
std.BoundedArray
- REMOVED. Use:
var buffer: [8]i32 = undefined; var stack = std.ArrayList(i32).initBuffer(&buffer);
Critical: Format Strings (0.15.x)
{f} required to call format methods:
// WRONG - ambiguous error std.debug.print("{}", .{std.zig.fmtId("x")});
// CORRECT std.debug.print("{f}", .{std.zig.fmtId("x")});
Format method signature changed:
// OLD - wrong pub fn format(self: @This(), comptime fmt: []const u8, opts: std.fmt.FormatOptions, writer: anytype) !void
// NEW - correct pub fn format(self: @This(), writer: *std.Io.Writer) std.Io.Writer.Error!void
Breaking Changes (0.14.0+)
@branchHint replaces @setCold
// WRONG @setCold(true);
// CORRECT @branchHint(.cold); // Must be first statement in block
@export takes pointer
// WRONG @export(foo, .{ .name = "bar" });
// CORRECT @export(&foo, .{ .name = "bar" });
Inline asm clobbers are typed
// WRONG : "rcx", "r11"
// CORRECT : .{ .rcx = true, .r11 = true }
@fence
- REMOVED
Use stronger atomic orderings or RMW operations instead.
Decl Literals (0.14.0+)
.identifier syntax works for declarations:
const S = struct { x: u32, const default: S = .{ .x = 0 }; fn init(v: u32) S { return .{ .x = v }; } };
const a: S = .default; // S.default const b: S = .init(42); // S.init(42) const c: S = try .init(1); // works with try
Labeled Switch (0.14.0+)
State machines use continue :label :
state: switch (initial) { .idle => continue :state .running, .running => if (done) break :state result else continue :state .running, .error => return error.Failed, }
Non-exhaustive Enum Switch (0.15.x)
Can mix explicit tags with _ and else :
switch (value) { .a, .b => {}, else => {}, // other named tags _ => {}, // unnamed integer values }
Quick Fixes
Error Fix
no field 'root_source_file'
Use root_module = b.createModule(.{...})
use of undefined value
Arithmetic on undefined is now illegal
type 'f32' cannot represent integer
Use float literal: 123_456_789.0 not 123_456_789
ambiguous format string
Use {f} for format methods
Version Info
-
0.15.x: Self-hosted x86_64 backend default for Debug (5x faster)
-
0.15.x: Use --watch -fincremental for incremental compilation
-
0.15.x: zig build --webui for build visualization
-
0.14.0+: LLVM 19; 0.15.x: LLVM 20
Language References
Load these references when working with core language features:
Language Basics & Built-ins
-
Language Basics - Core language: types, control flow (if/while/for/switch), error handling (try/catch/errdefer), optionals, structs, enums, unions, pointers, slices, comptime, functions
-
Built-in Functions - All @ built-ins: type casts (@intCast, @bitCast, @ptrCast), arithmetic (@addWithOverflow, @divExact), bit ops (@clz, @popCount), memory (@memcpy, @sizeOf), atomics (@atomicRmw, @cmpxchgWeak), introspection (@typeInfo, @TypeOf, @hasDecl), SIMD (@Vector, @splat, @reduce), C interop (@cImport, @export)
Standard Library References
Load these references when working with specific modules:
Memory & Slices
- std.mem - Slice search/compare, split/tokenize, alignment, endianness, byte conversion
Text & Encoding
-
std.fmt - Format strings, integer/float parsing, hex encoding, custom formatters, {f} specifier (0.15.x)
-
std.ascii - ASCII character classification (isAlpha, isDigit), case conversion, case-insensitive comparison
-
std.unicode - UTF-8/UTF-16 encoding/decoding, codepoint iteration, validation, WTF-8 for Windows
-
std.base64 - Base64 encoding/decoding (standard, URL-safe, with/without padding)
Math & Random
-
std.math - Floating-point ops, trig, overflow-checked arithmetic, constants, complex numbers, big integers
-
std.Random - PRNGs (Xoshiro256, Pcg), CSPRNGs (ChaCha), random integers/floats/booleans, shuffle, distributions
-
std.hash - Non-cryptographic hash functions (Wyhash, XxHash, FNV, Murmur, CityHash), checksums (CRC32, Adler32), auto-hashing
SIMD & Vectorization
- std.simd - SIMD vector utilities: optimal vector length, iota/repeat/join/interlace patterns, element shifting/rotation, parallel searching, prefix scans, branchless selection
Time & Timing
-
std.time - Wall-clock timestamps, monotonic Instant/Timer, epoch conversions, calendar utilities (year/month/day), time unit constants
-
std.Tz - TZif timezone database parsing (RFC 8536), UTC offsets, DST rules, timezone abbreviations, leap seconds
Sorting & Searching
- std.sort - Sorting algorithms (pdq, block, heap, insertion), binary search, min/max
Core Data Structures
-
std.ArrayList - Dynamic arrays, vectors, BoundedArray replacement
-
std.HashMap / AutoHashMap - Hash maps, string maps, ordered maps
-
std.ArrayHashMap - Insertion-order preserving hash map, array-style key/value access
-
std.MultiArrayList - Struct-of-arrays for cache-efficient struct storage
-
std.SegmentedList - Stable pointers, arena-friendly, non-copyable types
-
std.DoublyLinkedList / SinglyLinkedList - Intrusive linked lists, O(1) insert/remove
-
std.PriorityQueue - Binary heap, min/max extraction, task scheduling
-
std.PriorityDequeue - Min-max heap, double-ended priority extraction
-
std.Treap - Self-balancing BST, ordered keys, min/max/predecessor
-
std.bit_set - Bit sets (Static, Dynamic, Integer, Array), set operations, iteration
-
std.BufMap / BufSet - String-owning maps and sets, automatic key/value memory management
-
std.StaticStringMap - Compile-time optimized string lookup, perfect hash for keywords
-
std.enums - EnumSet, EnumMap, EnumArray: bit-backed enum collections
Allocators
- std.heap - Allocator selection guide, ArenaAllocator, DebugAllocator, FixedBufferAllocator, MemoryPool, SmpAllocator, ThreadSafeAllocator, StackFallbackAllocator, custom allocator implementation
I/O & Files
-
std.io - Reader/Writer API (0.15.x): buffered I/O, streaming, binary data, format strings
-
std.fs - File system: files, directories, iteration, atomic writes, paths
-
std.tar - Tar archive reading/writing, extraction, POSIX ustar, GNU/pax extensions
-
std.zip - ZIP archive reading/extraction, ZIP64 support, store/deflate compression
-
std.compress - Compression: DEFLATE (gzip, zlib), Zstandard, LZMA, LZMA2, XZ decompression/compression
Networking
-
std.http - HTTP client/server, TLS, connection pooling, compression, WebSocket
-
std.net - TCP/UDP sockets, address parsing, DNS resolution
-
std.Uri - URI parsing/formatting (RFC 3986), percent-encoding/decoding, relative URI resolution
Process Management
- std.process - Child process spawning, environment variables, argument parsing, exec
OS-Specific APIs
-
std.os - OS-specific APIs: Linux syscalls, io_uring, Windows NT APIs, WASI, direct platform access
-
std.c - C ABI types and libc bindings: platform-specific types (fd_t, pid_t, timespec), errno values, socket/signal/memory types, fcntl/open flags, FFI with C libraries
Concurrency
-
std.Thread - Thread spawning, Mutex, RwLock, Condition, Semaphore, WaitGroup, thread pools
-
std.atomic - Lock-free atomic operations: Value wrapper, fetch-and-modify (add/sub/and/or/xor), compare-and-swap, atomic ordering semantics, spin loop hints, cache line sizing
Patterns & Best Practices
- Zig Patterns - Load when writing new code or reviewing code quality. Comprehensive best practices extracted from the Zig standard library: quick patterns (memory/allocators, file I/O, HTTP, JSON, testing, build system) plus idiomatic code patterns covering syntax (closures, context pattern, options structs, destructuring), polymorphism (duck typing, generics, custom formatting, dynamic/static dispatch), safety (diagnostics, error payloads, defer/errdefer, compile-time assertions), and performance (const pointer passing)
Serialization
-
std.json - JSON parsing, serialization, dynamic values, streaming, custom parse/stringify
-
std.zon - ZON (Zig Object Notation) parsing and serialization for build.zig.zon, config files, data interchange
Testing & Debug
-
std.testing - Unit test assertions and utilities
-
std.debug - Panic, assert, stack traces, hex dump, format specifiers
-
std.log - Scoped logging with configurable levels and output
Metaprogramming
- std.meta - Type introspection, field iteration, stringToEnum, generic programming
Compiler Utilities
- std.zig - AST parsing, tokenization, source analysis, linters, formatters, ZON parsing
Security & Cryptography
- std.crypto - Hashing (SHA2, SHA3, Blake3), AEAD (AES-GCM, ChaCha20-Poly1305), signatures (Ed25519, ECDSA), key exchange (X25519), password hashing (Argon2, scrypt, bcrypt), secure random, timing-safe operations
Build System
- std.Build - Build system: build.zig, modules, dependencies, build.zig.zon, steps, options, testing, C/C++ integration