Zig
Up-to-date Zig programming language patterns for version 0.16.0. Use when writing, reviewing, or debugging Zig code, working with build.zig and build.zig.zon files, or using comptime metaprogramming. Critical for avoiding outdated patterns from training data - especially I/O interface (std.Io), build system APIs (root_module), container initialization (.empty/.init), allocator selection (DebugAllocator), and async/await patterns.From its SKILL.md
npx -y skills add zig-incubator/zig-skills --skill zigAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
17.8 KB, ~4.7k tokens by cl100k_base, as published. Nobody here has run it
Zig Language Reference (v0.16.0)
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.16.0)
usingnamespace - REMOVED
// WRONG - compile error
pub usingnamespace @import("other.zig");
// CORRECT - explicit re-export
const other = @import("other.zig");
pub const foo = other.foo;
GenericReader, AnyReader, FixedBufferStream - REMOVED (0.16.0)
These I/O types have been removed in favor of the new std.Io interface.
async/await - REMOVED then RESTORED
Keywords were removed from language in earlier versions but are now available again through std.Io interface.
Critical: I/O Interface (0.16.0)
Zig 0.16.0 introduces a complete rewrite of the I/O system using interfaces. The new std.Io provides async/await, concurrent operations, and multiple implementations.
Setting Up I/O
const std = @import("std");
const Io = std.Io;
pub fn main() !void {
// Set up allocator
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
defer debug_allocator.deinit();
const gpa = debug_allocator.allocator();
// Set up I/O implementation (choose one)
var threaded: std.Io.Threaded = .init(gpa);
defer threaded.deinit();
const io = threaded.io();
// Use I/O operations
try doWork(io);
}
fn doWork(io: Io) !void {
std.debug.print("working\n", .{});
io.sleep(.fromSeconds(1), .awake) catch {};
}
Async/Await Support
Async/await is back in Zig 0.16.0 with the new I/O interface:
fn doAsyncWork(io: Io) !void {
var future = io.async(someTask, .{io});
try future.await(io);
}
fn someTask(io: Io) !void {
std.debug.print("async task\n", .{});
io.sleep(.fromSeconds(1), .awake) catch {};
}
Concurrent Operations
For true parallelism:
fn doConcurrentWork(io: Io) !void {
var task1 = try io.concurrent(taskA, .{io});
var task2 = try io.concurrent(taskB, .{io});
try task1.await(io);
try task2.await(io);
}
fn taskA(io: Io) !void {
io.sleep(.fromSeconds(1), .awake) catch {};
}
fn taskB(io: Io) !void {
io.sleep(.fromSeconds(1), .awake) catch {};
}
File I/O with New Interface
fn readFile(io: Io, path: []const u8) ![]u8 {
const file = try std.fs.cwd().openFile(path, .{});
defer file.close();
// New allocation function
return file.readToEndAlloc(gpa, 1024 * 1024);
}
Note: Old buffered I/O patterns from 0.15.x are deprecated. Use the new std.Io interface instead.
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"));
Compile-level methods deprecated: exe.linkSystemLibrary(), exe.addCSourceFiles(),
exe.addIncludePath(), exe.linkLibC() are deprecated — use exe.root_module.* equivalents instead.
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+)
Arena Allocator is Now Thread-Safe
// 0.15.x: ArenaAllocator was not thread-safe
// 0.16.0: ArenaAllocator is now thread-safe and lock-free by default
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
// Safe to use from multiple threads
ThreadSafe Allocator Removed
// WRONG - 0.15.x pattern
const thread_safe = std.heap.ThreadSafe.allocator();
// CORRECT - 0.16.0: use ArenaAllocator (now thread-safe) or SmpAllocator
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
Thread.Pool Removed
// WRONG - 0.15.x pattern
var pool: std.Thread.Pool = .init(...);
// CORRECT - 0.16.0: use std.Io concurrent operations
var threaded: std.Io.Threaded = .init(gpa);
defer threaded.deinit();
const io = threaded.io();
var task = try io.concurrent(doWork, .{io});
File.Stat.access_time is Now Optional
// 0.15.x: access_time was always present
// 0.16.0: access_time is optional (may be null)
const stat = try file.stat();
if (stat.access_time) |atime| {
// Access time is available
}
@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 |
sanitize_c = true | Type changed to ?std.zig.SanitizeC — use .full, .trap, or .off |
std.fifo.LinearFifo | Removed — use std.Io.Reader/Writer patterns |
posix.sendfile | Removed — use std.fs.File writer .sendFileAll() |
std.fmt.Formatter | Deprecated — renamed to std.fmt.Alt |
fmtSliceEscapeLower/Upper | Use std.ascii.hexEscape(bytes, .lower/.upper) |
GenericReader, AnyReader, FixedBufferStream | Removed — use std.Io.Reader/Writer interface |
ThreadSafe allocator | Removed — use ArenaAllocator (now thread-safe) or SmpAllocator |
Thread.Pool | Removed — use std.Io.concurrent() for parallel work |
Language References
Load these references when working with core language features:
Code Style
- Style Guide - Official Zig naming conventions (TitleCase types, camelCase functions, snake_case variables), whitespace rules, doc comment guidance, redundancy avoidance,
zig fmt
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)
- Code Review - Load when reviewing Zig code. Systematic checklist organized by confidence level: ALWAYS FLAG (removed features, changed syntax, API changes), FLAG WITH CONTEXT (exception safety bugs, missing flush, allocator issues), SUGGEST (style improvements). Includes migration examples for 0.14/0.15 breaking changes
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
- Comptime Reference - Comptime fundamentals, type reflection (
@typeInfo/@Type/@TypeOf), loop variants (comptime forvsinline for), branch elimination, type generation, comptime limitations - 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
Interoperability
- C Interop - Exporting C-compatible APIs:
export fn, C calling convention, building static/dynamic libraries, creating headers, macOS universal binaries, XCFramework for Swift/Xcode, module maps
What ships with it: 55 files
625.7 KB alongside SKILL.md
references/
- builtins.md16.5 KB
- c-interop.md19.3 KB
- code-review.md41.4 KB
- comptime.md11.0 KB
- language.md13.7 KB
- patterns.md50.1 KB
- std-allocators.md17.2 KB
- std-array-hash-map.md4.8 KB
- std-arraylist.md4.4 KB
- std-ascii.md3.5 KB
- std-atomic.md11.8 KB
- std-base64.md3.8 KB
- std-bit-set.md4.5 KB
- std-buf-map.md3.9 KB
- std-build.md27.9 KB
- std-c.md25.4 KB
- std-compress.md10.2 KB
- std-crypto.md14.1 KB
- std-debug.md11.1 KB
- std-enums.md6.4 KB
- std-fmt.md13.1 KB
- std-fs.md10.8 KB
- std-hashmap.md3.6 KB
- std-hash.md11.7 KB
- std-http.md17.1 KB
- std-io.md9.3 KB
- std-json.md9.9 KB
- std-linked-list.md3.6 KB
- std-log.md5.9 KB
- std-math.md12.1 KB
- std-mem.md7.7 KB
- std-meta.md10.8 KB
- std-multi-array-list.md3.2 KB
- std-net.md14.5 KB
- std-os.md14.1 KB
- std-priority-dequeue.md3.7 KB
- std-priority-queue.md3.9 KB
- std-process.md13.4 KB
- std-random.md9.9 KB
- std-segmented-list.md2.9 KB
15 more files not listed here. See all 55 in the repository.