What zpack is
zpack bundles a directory tree into a single .zpak archive. It preserves
relative paths, streams file contents instead of buffering them, and guarantees
a byte-for-byte round trip.
It is two things sharing one implementation:
- a CLI, for packing assets in a build script or by hand
- a Zig library, so a program can open an archive and read from it directly
main.zig contains only argument handling. Everything the CLI does, the library
does too.
What it guarantees
Section titled “What it guarantees”A round trip is byte identical. Pack a directory, extract it, and diff -r
reports nothing. Every entry stores an XxHash64 of its original bytes, and that
hash is checked on every read, every verify, and every unpack.
The same tree produces the same archive. Entries are sorted by path before writing, so a repack is reproducible rather than dependent on directory walk order.
Nothing is held whole in memory. File contents move through reused 64 KiB buffers in both directions. A 40 GB asset directory packs in the same working set as a 40 MB one.
A malformed archive never causes an unchecked read. Archive.open validates
the entire index up front - every offset, every size, every path - so later
lookups work from data that has already been bounds checked. See
the security model.
An archive is never half written. pack builds into a temporary file beside
the destination and moves it into place only once it is complete, so a failed
run leaves any existing archive untouched.
What it does not do
Section titled “What it does not do”These are choices, not gaps to be filled later:
| Not supported | Why |
|---|---|
| Encryption or signing | The stored hash detects accidental corruption. It is not a MAC, and zpack does not authenticate archives. |
| Permissions, mtimes, symlinks | Only regular files get entries. An archive describes contents, not a filesystem. |
| Empty directories | Directories are implied by entry paths. One with nothing in it has nothing to imply it. |
| Appending to an existing archive | The index is written before the data, so adding an entry means rewriting the file. Repack instead. |
| Per-file compression settings | Each file is deflated at level 6 and kept only if the result is smaller. There is no knob. |
| Solid or cross-file compression | Each entry compresses independently, which is what makes reading one entry cheap. |
Requirements
Section titled “Requirements”zpack targets Zig 0.16.0 and uses the std.Io interfaces introduced there.
It does not build on 0.15 or earlier.