ZI

Zig Architecture Patterns

Idiomatic Zig architecture patterns using comptime, interfaces, and allocators

Details

Language / Topic
zigZig
Category
Architecture

Rules

balanced
- Pass `std.mem.Allocator` as the first argument to any function or struct that allocates memory — never use a global allocator implicitly.
- Use comptime-generated interfaces (a struct of function pointers) to achieve dynamic dispatch without the overhead of vtable indirection.
- Use `std.MultiArrayList` instead of `[]Struct` for arrays of structs with hot/cold field splits to improve cache efficiency in data-heavy code.
- Follow the `init` / `deinit` pattern for structs that own resources — `pub fn init(allocator: Allocator) !Self` and `pub fn deinit(self: *Self) void`.
- Use tagged unions (`const Shape = union(enum) { circle: Circle, rect: Rect };`) to model sum types and dispatch with `switch` for exhaustive handling.
- Expose C-compatible APIs via `pub export fn` with `callconv(.C)` for FFI boundaries — keep the Zig-idiomatic implementation behind a thin adapter.
- Use `build.zig` modules (`b.addModule`) to split large projects into independently compilable units with explicit dependency graphs.