archiver

A pure-Go library and CLI for creating, opening, and streaming zip, tar, and rar archives with multiple compression formats.

Library
Go
vv3.5.1
4,378stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
46/100Fair
Development Activity0
Maintenance20
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
66/100Good
Architecture78
Code Quality62
Innovation45
Learning Curve80

Archiver (v3) is a cross-platform Go library and companion CLI (arc) for creating, extracting, and inspecting archive files without shelling out to platform-specific tools like tar or zip. It supports .zip, .tar (with any compressed variant), and read-only .rar archives, paired with brotli, bzip2, gzip, lz4, snappy, xz, and zstandard compression formats — all implemented in pure Go with no cgo or external dependencies.

The library exposes both simple package-level convenience functions (Archive, Unarchive, Walk, Extract, CompressFile, DecompressFile) that infer format from file extension, and fully configurable per-format types (Zip, Tar, TarGz, etc.) implementing small, composable interfaces (Archiver, Unarchiver, Writer, Reader, Walker, Extractor, Compressor, Decompressor). This lets callers stream archive contents in and out of io.Reader/io.Writer without touching disk, which is useful for serving archives directly over HTTP or processing them in memory.

The project has since been superseded by mholt/archives (v4), which the maintainer describes as having an improved, more conventional API and better performance — archiver v3 is no longer actively developed but remains in wide use and continues to receive the occasional maintenance fix.

What You Get

  • Package-level convenience functions (Archive, Unarchive, Walk, Extract, CompressFile, DecompressFile) that infer format from file extension
  • Per-format configurable types (Zip, Tar, TarGz, TarBz2, TarXz, TarZstd, TarLz4, TarSz, TarBrotli, Gz, Bz2, Xz, Zstd, Lz4, Snappy, Brotli) for fine-grained control over compression level, overwrite behavior, and top-level folder handling
  • Streaming Reader/Writer interfaces so archives can be built or read entirely in memory via io.Reader/io.Writer, without touching disk
  • A cross-platform arc CLI binary (no external dependencies, not even libc) for archive/unarchive/list/extract/compress/decompress from the command line
  • Read-only RAR extraction support, including password-protected archives
  • Walker interface to traverse and inspect archive contents (including per-file headers) without extracting to disk first

Common Use Cases

  • Packaging build artifacts or release binaries into .tar.gz or .zip files as part of a Go-based CI/release tool
  • Streaming a dynamically generated .zip archive directly to an HTTP response without writing temp files
  • Extracting a single file or subdirectory out of a large tarball without unpacking the whole thing
  • Inspecting the contents and headers of an untrusted archive with Walk before deciding whether to extract it
  • Building a cross-platform CLI tool that needs to compress/decompress files without depending on system tar/zip binaries

Under The Hood

Architecture Package-level functions in archiver.go (Archive, Unarchive, Walk, Extract, CompressFile, DecompressFile) route to per-format implementations via ByExtension/ByHeader, which inspect a filename or file header against a registry of extension checkers and matchers. Each supported format (Tar, Zip, Gz, and composed variants like TarGz, TarBz2, TarXz, TarZstd) implements a handful of small, composable interfaces defined directly in archiver.go — Archiver, Unarchiver, Reader, Writer, Walker, Extractor, Compressor, Decompressor — so a single struct can satisfy several roles at once. The compressed-tar variants (tarbz2.go, targz.go, tarxz.go, tarzst.go) are thin glue files that wrap a Tar value together with its matching compressor/decompressor, rather than reimplementing tar handling. Everything ultimately flows through the File/FileInfo wrapper types that bridge real filesystem entries and in-archive entries, so any change to that core abstraction would ripple through every format wrapper.

Tech Stack Written entirely in pure Go with no cgo, targeting Go 1.13. Dependencies are narrowly scoped to one library per format: andybalholm/brotli, dsnet/compress (bzip2 writing), golang/snappy, klauspost/compress plus klauspost/pgzip (multithreaded gzip), nwaples/rardecode (RAR reading), pierrec/lz4, ulikunitz/xz, and xi2/xz. There is no web framework, database, or ORM involved — this is a standalone library paired with a single arc CLI binary built straight from cmd/arc, with no CLI framework dependency. CI runs across Ubuntu, macOS, and Windows via GitHub Actions against multiple Go versions, and goreleaser drives cross-platform binary builds for linux/windows/darwin across several architectures.

Code Quality Test coverage spans the core archiver behavior, tar-specific handling, error paths, and the file-compressor helper, all using the standard library testing package with no external assertion library — idiomatic but comparatively terse Go testing style. Error handling favors wrapping with fmt.Errorf for context rather than typed sentinel errors, aside from a couple of package-level errors (ErrStopWalk, ErrFormatNotRecognized) used to signal control flow during walks. No dedicated linter configuration is present beyond what CI runs implicitly; naming follows conventional Go idioms throughout (exported PascalCase API surface, unexported lowercase helpers).

API Design The library deliberately offers two tiers of ergonomics: one-line package-level calls for the common case, and fully configurable per-format structs (compression level, overwrite behavior, top-level folder handling) for callers who need control. Documentation is thorough — extensive GoDoc comments throughout archiver.go plus README examples covering both CLI and library usage, including streaming archives directly into an io.Writer. The project is explicit about scope limits, notably declining to mitigate zip-slip attacks itself and instead pushing that responsibility onto callers via the Walk inspection API — a deliberate simplicity-over-completeness tradeoff rather than an oversight. The overall design is a conventional, well-executed wrapper over existing pure-Go compression libraries rather than a novel approach to archiving.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search