Zig’s standard library is imported with:
const std = @import("std");Most useful standard library APIs live under std.
This appendix is a beginner map. It does not cover every function. It shows the parts you will use most often.
D.1 Printing
Use std.debug.print for simple output while learning.
const std = @import("std");
pub fn main() void {
std.debug.print("Hello\n", .{});
}With values:
std.debug.print("x = {}\n", .{x});With strings:
std.debug.print("name = {s}\n", .{name});Common format patterns:
| Pattern | Meaning |
|---|---|
{} | Default formatting |
{s} | String formatting |
{any} | Debug-style formatting |
D.2 Testing
Use std.testing for unit tests.
const std = @import("std");
fn add(a: i32, b: i32) i32 {
return a + b;
}
test "add works" {
try std.testing.expect(add(2, 3) == 5);
}Run:
zig test main.zigUseful testing APIs:
| API | Use |
|---|---|
std.testing.expect | Assert that a condition is true |
std.testing.expectEqual | Compare expected and actual values |
std.testing.expectError | Check that an error happens |
std.testing.allocator | Allocator for tests |
D.3 Memory Allocation
Zig does not hide heap allocation. Many APIs ask for an allocator.
Common allocator type:
std.mem.AllocatorPage allocator:
const allocator = std.heap.page_allocator;General-purpose allocator pattern:
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();Arena allocator pattern:
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();Allocate bytes:
const buf = try allocator.alloc(u8, 1024);
defer allocator.free(buf);Important APIs:
| API | Use |
|---|---|
allocator.alloc(T, n) | Allocate n items of type T |
allocator.free(slice) | Free allocated slice |
allocator.create(T) | Allocate one item |
allocator.destroy(ptr) | Free one item |
std.heap.page_allocator | Simple allocator backed by OS pages |
std.heap.GeneralPurposeAllocator | Debug-friendly general allocator |
std.heap.ArenaAllocator | Many allocations, one cleanup |
D.4 Memory Utilities
std.mem contains functions for working with slices, bytes, and memory.
Compare slices:
if (std.mem.eql(u8, a, b)) {
// same bytes
}Copy bytes:
@memcpy(dest, source);Fill bytes:
@memset(buffer, 0);Find value:
const index = std.mem.indexOf(u8, text, "needle");Useful APIs:
| API | Use |
|---|---|
std.mem.eql | Compare slices |
std.mem.indexOf | Find subslice |
std.mem.startsWith | Check prefix |
std.mem.endsWith | Check suffix |
std.mem.trim | Trim characters |
std.mem.splitScalar | Split by one byte |
std.mem.tokenizeScalar | Tokenize by one byte |
D.5 ArrayList
std.ArrayList is a growable array.
var list = std.ArrayList(i32).init(allocator);
defer list.deinit();
try list.append(10);
try list.append(20);Access items:
for (list.items) |item| {
std.debug.print("{}\n", .{item});
}Useful APIs:
| API | Use |
|---|---|
append | Add one item |
appendSlice | Add many items |
pop | Remove last item |
clearRetainingCapacity | Clear but keep memory |
clearAndFree | Clear and free memory |
items | Slice of stored items |
D.6 Hash Maps
String keys:
var map = std.StringHashMap(i32).init(allocator);
defer map.deinit();
try map.put("one", 1);
try map.put("two", 2);Get a value:
if (map.get("one")) |value| {
std.debug.print("{}\n", .{value});
}Generic hash map:
std.AutoHashMap(K, V)Useful APIs:
| API | Use |
|---|---|
put | Insert or replace |
get | Read value |
contains | Check key |
remove | Remove key |
iterator | Iterate entries |
count | Number of entries |
D.7 Files
Open a file:
const file = try std.fs.cwd().openFile("data.txt", .{});
defer file.close();Create a file:
const file = try std.fs.cwd().createFile("out.txt", .{});
defer file.close();Read and write APIs vary by Zig version. In Zig 0.16, newer I/O APIs use the std.Io model. The main idea remains the same: open files through std.fs, then read or write through the appropriate reader or writer API.
Directory APIs:
| API | Use |
|---|---|
std.fs.cwd() | Current working directory |
openFile | Open existing file |
createFile | Create or truncate file |
makeDir | Create directory |
deleteFile | Delete file |
openDir | Open directory |
close | Close file or directory handle |
D.8 Paths
Use std.fs.path for path operations.
const base = std.fs.path.basename("/tmp/file.txt");Useful APIs:
| API | Use |
|---|---|
basename | Last path component |
dirname | Parent path |
extension | File extension |
join | Join path parts |
isAbsolute | Check absolute path |
Path handling is platform-sensitive. Avoid manual string concatenation for paths.
D.9 Formatting
Use std.fmt for converting values to text.
Format into a buffer:
var buf: [64]u8 = undefined;
const text = try std.fmt.bufPrint(&buf, "x = {}", .{x});Parse integer:
const n = try std.fmt.parseInt(i32, "123", 10);Parse float:
const f = try std.fmt.parseFloat(f64, "3.14");Useful APIs:
| API | Use |
|---|---|
bufPrint | Format into fixed buffer |
allocPrint | Format into allocated string |
parseInt | Parse integer |
parseFloat | Parse float |
format | Custom formatting support |
D.10 Math
Use std.math.
const x = std.math.sqrt(16.0);Common APIs:
| API | Use |
|---|---|
sqrt | Square root |
sin, cos, tan | Trigonometry |
log, log2, log10 | Logarithms |
min, max | Minimum and maximum |
clamp | Clamp value into range |
absInt | Absolute value for integers |
Some operations may return errors or require specific types. Read the function signature.
D.11 Random Numbers
Use std.Random.
A common pattern:
var prng = std.Random.DefaultPrng.init(12345);
const random = prng.random();
const n = random.int(u32);For serious security-sensitive randomness, use a cryptographic random source, not a deterministic PRNG.
Useful APIs:
| API | Use |
|---|---|
random.int(T) | Random integer |
random.float(T) | Random float |
random.boolean() | Random bool |
random.bytes(buf) | Fill buffer with random bytes |
D.12 Time
Use std.time.
const start = std.time.nanoTimestamp();
// work
const end = std.time.nanoTimestamp();
const elapsed = end - start;Useful APIs:
| API | Use |
|---|---|
nanoTimestamp | Current timestamp in nanoseconds |
milliTimestamp | Current timestamp in milliseconds |
sleep | Sleep for a duration |
ns_per_s | Nanoseconds per second |
ms_per_s | Milliseconds per second |
D.13 Process
Use std.process for process-level data and child processes.
Common needs:
| API area | Use |
|---|---|
| Arguments | Read command-line arguments |
| Environment | Read environment variables |
| Child process | Run another program |
| Exit code | Control process result |
In Zig 0.16, process arguments and environment handling are less global and fit better with explicit I/O design. Expect examples to pass context more explicitly than older Zig code.
D.14 Sorting
Use std.sort.
Example idea:
std.sort.heap(i32, items, {}, lessThan);Comparator:
fn lessThan(_: void, a: i32, b: i32) bool {
return a < b;
}Sorting APIs may vary by version, so check the exact signature for your Zig release.
D.15 JSON
Use std.json.
Common operations:
| Task | API area |
|---|---|
| Parse JSON | std.json.parseFromSlice |
| Build JSON text | std.json.stringify |
| Read dynamic JSON | std.json.Value |
| Parse into struct | typed parsing APIs |
Example type:
const User = struct {
name: []const u8,
age: u32,
};JSON APIs often need an allocator because parsed data may allocate memory.
D.16 HTTP
Zig’s standard library includes HTTP support, but HTTP APIs have changed across releases.
For beginner projects, learn these ideas first:
| Concept | Meaning |
|---|---|
| Client | Sends HTTP requests |
| Server | Receives HTTP requests |
| Headers | Metadata such as content type |
| Body | Request or response data |
| Method | GET, POST, PUT, etc. |
| Status | Response code such as 200 or 404 |
When using Zig 0.16, prefer examples written for Zig 0.16 because older HTTP examples may not compile unchanged.
D.17 Logging
Use std.log.
std.log.info("server started on port {}", .{port});Levels:
| Level | Use |
|---|---|
debug | Detailed debugging |
info | Normal information |
warn | Suspicious but recoverable situation |
err | Error condition |
D.18 Threading
Use std.Thread.
Example shape:
const thread = try std.Thread.spawn(.{}, worker, .{});
thread.join();Worker:
fn worker() void {
// work here
}Related APIs:
| API | Use |
|---|---|
std.Thread.spawn | Start a thread |
join | Wait for thread |
std.Thread.Mutex | Mutual exclusion |
std.Thread.Condition | Wait and signal |
std.atomic | Atomic operations |
D.19 Networking
Use std.net for networking.
Common concepts:
| Concept | Meaning |
|---|---|
| Address | IP address plus port |
| TCP | Reliable byte stream |
| UDP | Datagram protocol |
| Listener | Waits for incoming connections |
| Stream | Read/write connection |
Networking code usually involves I/O, errors, buffers, and careful resource cleanup.
D.20 Build System
The build system uses build.zig.
Common names:
| API | Use |
|---|---|
std.Build | Build system root type |
addExecutable | Add executable target |
addTest | Add test target |
addRunArtifact | Run a build artifact |
standardTargetOptions | Target selection |
standardOptimizeOption | Debug/release mode |
A small build script creates an executable, sets its root source file, and installs it.
D.21 C Interop
Zig can import C headers:
const c = @cImport({
@cInclude("stdio.h");
});Then call C functions:
_ = c.printf("hello\n");Zig can also compile C code through:
zig ccThis is one of Zig’s practical strengths.
D.22 Common Import Map
| Import | Use |
|---|---|
std.debug | Debug printing |
std.testing | Tests |
std.mem | Memory and slice utilities |
std.heap | Allocators |
std.fs | Filesystem |
std.fs.path | Path handling |
std.fmt | Formatting and parsing |
std.math | Math helpers |
std.time | Time |
std.process | Process APIs |
std.json | JSON |
std.log | Logging |
std.Thread | Threads |
std.net | Networking |
std.Build | Build system |
D.23 How to Read Standard Library Code
The standard library is ordinary Zig code.
When documentation is unclear, open the source.
Look for:
| What to check | Why it matters |
|---|---|
| Function signature | Shows arguments, errors, and return type |
| Allocator parameter | Means the function may allocate |
| Error union | Means the function can fail |
comptime parameter | Means value is known at compile time |
defer usage | Shows cleanup rules |
| Tests | Show intended behavior |
A useful habit is to read signatures before reading implementation.
Example:
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !TThis tells you a lot:
T is known at compile time.
buf is the input text.
radix is the base, such as 10 or 16.
The function may fail.
The successful result has type T.
D.24 What to Memorize First
For beginners, memorize these first:
| API | Why |
|---|---|
@import("std") | Every Zig file uses it often |
std.debug.print | Basic output |
std.testing.expect | Basic tests |
std.mem.eql | Compare strings and slices |
std.heap.page_allocator | Simple allocation |
std.ArrayList | Growable arrays |
std.StringHashMap | String-key maps |
std.fs.cwd() | File operations |
std.fmt.parseInt | Parse numbers |
defer with close or free | Cleanup |
Do not try to memorize the whole standard library. Learn it by solving small problems.