# Zig quickstart
This is a ~60-second round-trip: snapshot a directory, `push` it to a local
`file://` store, then `pull` it back and confirm the ID matches. Snapshot IDs
are 64-character lowercase hex and **bit-identical** to the CLI and every other
binding, so the ID you print here is the exact string `snapdir id` produces.
## 1. Install
Build the `snapdir-ffi` C ABI from crates.io and `zig fetch --save` the wrapper
(Zig 0.13.0). See [Install snapdir for Zig](/install/zig/) for the full recipe,
including the Alpine/musl `libgcc_s` note.
## 2. Snapshot + push
Compute the snapshot ID for a directory, then push it to a local store. The
store URI is always an argument — `file://$PWD/store` needs no setup:
```zig
const std = @import("std");
const snapdir = @import("snapdir");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const a = gpa.allocator();
const store = try std.fmt.allocPrintZ(a, "file://{s}/store", .{
try std.process.getEnvVarOwned(a, "PWD"),
});
defer a.free(store);
// Walk ./my-dir → 64-char snapshot id ([64]u8 value, no free).
const id = try snapdir.id(a, "./my-dir", .{});
std.debug.print("id: {s}\n", .{id});
// Upload the snapshot to the store; returns the same id.
const pushed = try snapdir.push(a, "./my-dir", store, .{});
std.debug.print("pushed: {s}\n", .{pushed});
}
```
This prints a 64-character lowercase hex ID, e.g. ``.
## 3. Pull it back
Materialise the snapshot into a fresh directory and recompute its ID — it is the
same 64-hex string:
```zig
// pull(id, store, dest) restores the snapshot into ./restored.
try snapdir.pull(a, &pushed, store, "./restored", .{});
const restored_id = try snapdir.id(a, "./restored", .{});
std.debug.print("restored: {s}\n", .{restored_id}); // == id
```
That is the same snapshot ID you would get from `snapdir id` or `snapdir push`
on the command line — the Zig binding and the CLI share one Rust core.