|claim|login
RepoCritics — Review. Share. Archive. Every open-source repo.

guzba/zippy

Wiki: guzba/zippy

Source: https://github.com/guzba/zippy

Last synced 2026-07-18 · 1087 words · Edit wiki on GitHub →

guzba/zippy

> Pure Nim implementation of DEFLATE, zlib, gzip, zip, and tar — no C dependencies, competitive with zlib on speed.

GitHub repo · API reference · License: MIT

Overview

Zippy is a compression library for Nim that implements the DEFLATE (RFC 1951), zlib (RFC 1950), and gzip (RFC 1952) formats from scratch, plus reading of ZIP archives and tarballs (.tar, .tar.gz, .tgz)1. Its explicit design goal is to be small, fast, and dependency-free: unlike the official nim-lang/zip package, which binds to C zlib and libzip, Zippy links nothing external. That matters in Nim because cross-compilation and static binaries are common use cases, and dragging in a system zlib is a frequent source of Windows/macOS build friction.

The trade the library makes is reimplementation risk in exchange for build simplicity. The author mitigates this with a cross-implementation validation suite (tests/validate.nim round-trips data against other DEFLATE implementations) and fuzzing (tests/fuzz.nim, tests/stress.nim)1. The project is by Ryan Oldenburg (guzba), whose sibling libraries — Pixie (2D graphics) and Mummy (HTTP server) — consume Zippy for PNG zlib streams and HTTP gzip respectively, so the code is exercised more widely than its 282-star count suggests.

Maintenance is slow-cadence but real: created October 2020, latest tagged release 0.10.19 (March 2026), last push May 20262. It is a mature library in maintenance mode rather than an actively evolving one — 0.10.x has been the series since mid-2022.

Getting Started

nimble install zippy

Compress and decompress in-memory data:

import zippy

let compressed = compress("Hello, compression!", BestCompression, dfGzip)
let original = uncompress(compressed, dfGzip)
assert original == "Hello, compression!"

Extract a ZIP archive or tarball:

import zippy/ziparchives

extractAll("archive.zip", "output_dir/")

The dfDetect data format sniffs zlib vs gzip headers on decompression, which is convenient for HTTP Content-Encoding handling (see the examples/ folder for HTTP client/server gzip usage)1.

Architecture / How It Works

Zippy is a from-scratch DEFLATE codec: LZ77 match finding with hash chains feeding canonical Huffman coding, with the standard compression-level dial trading match-search effort for ratio (BestSpeed through BestCompression, mirroring zlib's level semantics). Decompression validates the adler32 (zlib) or crc32 (gzip) checksums the wrappers require. Everything operates on Nim strings/seqs in memory — there is no incremental streaming interface equivalent to zlib's z_stream, which is the most important architectural fact about the library (see Production Notes).

The archive layer sits on top: zippy/ziparchives parses the ZIP central directory and inflates entries (deflate and store methods), and zippy/tarballs handles tar with optional gzip. Reading/extraction is the mature path; archive creation is supported but historically narrower in scope than extraction, and the archive APIs were reworked during the 0.10 series.

Portability is a first-class concern: the library is tested under Nim's default GC and --gc:arc/--gc:orc, under both nim c and nim cpp, and with MSVC (--cc:vcc) on Windows1. This makes it a safe dependency for libraries that cannot dictate their consumers' toolchain — which is exactly how Pixie uses it.

Production Notes

  • No streaming API. compress/uncompress take and return whole buffers. Decompressing a multi-gigabyte gzip file means holding both input and output in memory. If you need bounded-memory streaming (log pipelines, proxies), Zippy is the wrong shape; bind C zlib or zstd instead.
  • Untrusted input. The codec has been fuzzed against crashes1, but DEFLATE's ~1000:1 amplification still applies: a small malicious payload can expand to a huge allocation. Enforce your own size limits before decompressing untrusted data — the whole-buffer API gives you no natural backpressure point.
  • Performance is genuinely good, but self-reported. The README's benchmarks (Ryzen 5 5600X) show roughly 1.5–2x faster than stock-Linux zlib on both compress and uncompress3. These are the author's numbers against nim-lang/zip; run tests/benchmark.nim on your own workload. The baseline is stock zlib, not zlib-ng or libdeflate, which narrow or reverse the gap.
  • ZIP feature coverage. Expect the common cases (deflate/store entries) to work. Encrypted ZIPs and exotic compression methods are not supported; if you ingest arbitrary user-uploaded archives, validate against your corpus first.
  • Bus factor and cadence. Effectively a single-maintainer project with months-long release gaps (0.10.16 in Aug 2024 → 0.10.17 in Dec 2025)2. The library is small and stable enough that vendoring is a realistic fallback. Still 0.x after five years; the API has been stable through 0.10.x, but the archive-module rework earlier in 0.x broke consumers once.

When to Use / When Not

Use when:

  • You are writing Nim and want gzip/zlib/deflate without any C toolchain or system-library dependency (static binaries, cross-compilation, Windows).
  • You need HTTP gzip encoding/decoding in a Nim service or client.
  • You need to read ZIP/tar archives whose contents fit comfortably in memory.
  • You are already in the guzba/treeform ecosystem (Pixie, Mummy) — it is the native choice there.

Avoid when:

  • You need streaming compression with bounded memory — whole-buffer only.
  • You need maximum-trust decompression of hostile input at scale; C zlib, zlib-ng, or libdeflate have vastly larger deployment and audit surface.
  • You need modern formats (zstd, brotli, xz) — Zippy is DEFLATE-family only.
  • You need full ZIP feature coverage (encryption, ZIP64 edge cases, uncommon methods) for arbitrary third-party archives.

Alternatives

  • nim-lang/zip — official Nim wrapper over C zlib/libzip; use it when you want the battle-tested C implementation and can tolerate the external dependency.
  • madler/zlib — the reference C implementation; bind it directly when ecosystem trust and streaming matter more than pure-Nim builds.
  • richgel999/miniz — single-file C DEFLATE+ZIP; a comparable "easy to embed" choice for C/C++ codebases rather than Nim.
  • facebook/zstd — different format entirely; use when you control both ends of the pipe and want better ratio-speed tradeoffs than DEFLATE.
  • guzba/supersnappy — same author, pure Nim Snappy; use for speed-over-ratio internal data paths where format compatibility with gzip/zlib is not required.

History

VersionDateNotes
initial2020-10Repo created; pure-Nim deflate/zlib/gzip2.
0.10.02022-06Start of the long-running 0.10.x series2.
0.10.162024-08Last release before a ~16-month gap2.
0.10.17–182025-12Maintenance releases2.
0.10.192026-03Latest tagged release2.
2026-05Last push: macOS nim cpp compatibility fix2.

References

  1. ^ Zippy README — formats, goals, validation, fuzzing, GC/compiler support. https://github.com/guzba/zippy#readme
  2. ^ GitHub releases and commit history for guzba/zippy. https://github.com/guzba/zippy/releases
  3. ^ Zippy README, "Performance" — author-run benchmarks vs nim-lang/zip on Ryzen 5 5600X. https://github.com/guzba/zippy#performance

Tags

nim, compression, deflate, gzip, zlib, zip-archive, tarball, lz77, huffman-coding, library