Zig Best Practices
Follows type-first, functional, and error handling patterns from CLAUDE.md. This skill covers Zig-specific idioms only.
Type System Patterns
Tagged unions for mutually exclusive states — prevents invalid combinations that a struct with multiple nullable fields would allow:
Explicit error sets — documents exactly what can fail; anyerror hides failure modes:
Distinct types for domain IDs — compiler prevents mixing up different ID types:
Comptime validation — catch invalid configurations at compile time, not runtime:
Memory Management
- Pass allocators explicitly to every function that allocates; no global allocator state.
- Place
defer resource.deinit()immediately after acquisition — keeps cleanup co-located with creation. - Use
errdeferfor cleanup on error paths;deferfor unconditional cleanup. - Use arena allocators for batch/temporary work; they free everything at once.
- Use
std.testing.allocatorin tests — reports leaks with stack traces.
Key Conventions
- Prefer
constovervar; prefer slices over raw pointers. - Prefer
comptime T: typeoveranytype; explicit types produce clearer errors. Useanytypeonly for genuinely polymorphic cases (callbacks,std.debug.print-style). - Exhaustive
switch: include anelsereturning an error orunreachablefor truly impossible cases. - Use
std.log.scoped(.module_name)for namespaced logging; define a module-levelconst logconstant. - Larger cohesive files are idiomatic — tests alongside implementation, comptime generics at file scope.
Advanced Topics
- Generic containers (queues, stacks, trees): See GENERICS.md [blocked]
- C library interop (raylib, SDL, curl): See C-INTEROP.md [blocked]
- Debugging memory leaks (GPA, stack traces): See DEBUGGING.md [blocked]
Tooling
zigdoc — browse std library and dependency docs:
ziglint — static analysis with .ziglint.zon config:
References
- Language Reference: https://ziglang.org/documentation/0.15.2/
- Standard Library: https://ziglang.org/documentation/0.15.2/std/
- Zig Guide: https://zig.guide/


