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 2026[^2]. 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 Windows[^1]. 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 crashes[^1], 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 uncompress[^3]. 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

| Version | Date | Notes | |---------|------|-------| | initial | 2020-10 | Repo created; pure-Nim deflate/zlib/gzip[^2]. | | 0.10.0 | 2022-06 | Start of the long-running 0.10.x series[^2]. | | 0.10.16 | 2024-08 | Last release before a ~16-month gap[^2]. | | 0.10.17–18 | 2025-12 | Maintenance releases[^2]. | | 0.10.19 | 2026-03 | Latest tagged release[^2]. | | — | 2026-05 | Last push: macOS nim cpp compatibility fix[^2]. |

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