High-performance, feature-rich library for creating, reading, modifying and extracting ZIP archives in Go
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-27 06:15:54 +01:00
pkg feat: initial implementation code 2026-09-27 05:56:27 +01:00
.gitignore init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
.markdownlint-cli2.jsonc init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
.nwa-config.yaml init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
archiver.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
archiver_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
compression.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
conflict.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
COPYING.md init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
encoding.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
encryption.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
encryption_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
errors.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
file.go fix: fix rename of internal 2026-09-27 06:15:54 +01:00
file_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
fuzz_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
go.mod init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
LICENSE init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
options.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
reader.go fix: fix rename of internal 2026-09-27 06:15:54 +01:00
reader_test.go fix: fix rename of internal 2026-09-27 06:15:54 +01:00
README.md feat: initial implementation code 2026-09-27 05:56:27 +01:00
SECURITY.md init: initial commit with initial base files 2026-09-27 05:49:14 +01:00
sort.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
sort_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
utils.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
utils_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
writer.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
writer_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
zip.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
zip_fs.go feat: initial implementation code 2026-09-27 05:56:27 +01:00
zip_test.go feat: initial implementation code 2026-09-27 05:56:27 +01:00

GMS-Zip - High Performance archive/zip replacement

A high-performance, concurrency-safe replacement for the standard archive/zip.

GMS-Zip is designed for high-load applications where speed, security, and interface flexibility are critical. It treats file systems, memory buffers, and network streams as first-class citizens, allowing you to manipulate archives without managing temporary files or complex buffers.

At a Glance

Why switch from the standard library?

Feature archive/zip (StdLib) GMS-Zip
Concurrency Single-threaded Parallel (Multi-core)
Performance Baseline ~4x Faster (See Benchmarks)
Security Vulnerable to Zip Slip Native Protection
I/O Source File / ReaderAt Polymorphic (File, URL, Buffer)
Encryption Legacy ZipCrypto (Read-only) AES-256 & ZipCrypto (R/W)
Editing Append only Modify / Rename / Remove
Control No cancellation Context-aware

Key Capabilities

  • Cloud-Native I/O: Stream archives directly from HTTP/S3 to the client without touching the disk.
  • No External Dependencies The core library relies strictly on the Go standard library.
  • Zero-Overhead Abstraction: Unified API for files, bytes, and streams using Source and Sink interfaces.
  • The Archiver Pattern: No global state side-effects. Configure passwords and codecs once, reuse everywhere.
  • Resilience: "Best Effort" strategy collects all errors (errors.Join) instead of failing on the first file.
  • Legacy Support: Automatically handles Zip64, NTFS timestamps, Unix permissions, and CP866 (DOS) encodings.

Performance Benchmarks

GMS-Zip utilizes a fixed worker pool, memory pooling (sync.Pool), and a Zero-Allocation pipeline. It achieves massive speedups while maintaining allocation parity with the standard library.

Environment: Intel Core i5-12400F (6 cores, 12 threads)

Compression Speed

Scenario Standard Lib GMS-Zip (Sequential) GMS-Zip (Parallel) Speedup
1,000 Small Files 14.3 ms 15.0 ms 3.9 ms 3.7x faster
10 Medium Files (100MB) 179.8 ms 177.9 ms 42.2 ms 4.3x faster

Memory Efficiency

Metric Standard Lib GMS-Zip (Sequential) GMS-Zip (Parallel) Impact
Allocations 12,016 op 12,078 op 12,568 op < 5% overhead
Memory Usage 0.48 MB/op 1.71 MB/op 13.8 MB/op Bounded by worker count

Note: GMS-Zip trades a fixed amount of buffer memory (per worker) to saturate CPU cores, ensuring the GC remains idle even under heavy load.


Installation

go get rtlabs.tech/gms-zip

Usage Guide

The One-Liners (Simple)

For 90% of use cases, use the static helpers with safe defaults (Deflate compression, auto-detection).

package main

import "rtlabs.tech/gms-zip"

func main() {
  // Archive a directory to a file
  gmszip.ArchiveDir("data/images", gmszip.ToFilePath("backup.zip"))

  // Extract specific files
  gmszip.Unzip(
    gmszip.FromFilePath("backup.zip"),
    "restored/",
    gmszip.WithFromDir("images"), // Extract only this folder
  )

  // Read single file content directly into memory
  data, _ := gmszip.ReadFile(gmszip.FromFilePath("logs.zip"), "error.log")
}

The Archiver (Configured)

Use NewArchiver when you need specific settings (encryption, compression levels) isolated from the rest of your app.

func main() {
  // Create a reusable configuration
  archiver := gmszip.NewArchiver(
    gmszip.WithArchivePassword("secure-password-123"),
    gmszip.WithCompression(gmszip.ZStandard, zstd.SpeedBestCompression),
    // gmszip.WithWorkers(4), // Optional: Limit concurrency
  )

  ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
  defer cancel()

  // Use it for multiple operations
  err := archiver.UnzipWithContext(ctx, gmszip.FromFilePath("encrypted.zip"), "out/")
}

Modifying Archives (Edit Mode)

GMS-Zip allows surgical modifications to existing archives (Edit-in-place logic).

func main() {
  archive := gmszip.NewZip()
    
  // Load existing metadata (lightweight, doesn't read contents yet)
  src, _ := os.Open("app.zip")
  archive.LoadFromFile(src)
  src.Close()

  // Modify structure
  archive.Remove("logs/")
  archive.Rename("config.dev.json", "config.json")
    
  // Add new file dynamically (Lazy execution)
  archive.AddLazy("db.dump", func() (io.ReadCloser, error) {
    return exec.Command("pg_dump", "db").StdoutPipe()
  })

  // Write the new version
  out, _ := os.Create("app_v2.zip")
  archive.WriteTo(out)
}

Advanced: Polymorphic I/O

You can perform operations on any Source (File, URL, Buffer) using the unified API.

// Calculate SHA256 of a remote ZIP without storing it on disk
func HashRemoteZip(url string) string {
  h := sha256.New()
    
  // GMS-Zip handles the HTTP range requests or buffering automatically
  gmszip.UseSource(gmszip.FromURL(url, http.DefaultClient), 
    func(r io.Reader, _ io.ReaderAt, _ int64) error {
      _, err := io.Copy(h, r)
      return err
    },
  )
  return hex.EncodeToString(h.Sum(nil))
}

Configuration & Options

Functional Options

Configure operations per-file or per-archive:

  • WithName("new.txt"): Rename file inside the archive.
  • WithCompression(method, level): Override compression.
  • WithEncryption(method, password): Set AES-256 or ZipCrypto.
  • WithWorkers(n): Set number of parallel workers.
  • WithProgress(callback): track progress of operations.

Filters

Selectively process files:

  • WithOnly([]*File): Whitelist specific files.
  • WithFromDir("folder"): Restrict operation to a specific directory.
  • WithExcludeDir("folder"): Blacklist a directory.

Sorting Strategies

  • SortDefault: Preserves insertion order.
  • SortAlphabetical: Deterministic order (A-Z).
  • SortSizeDescending: Ensures heavy files don't block the output queue in parallel mode.
  • SortZIP64Optimized: Buckets files by size to optimize Zip64 header overhead.

Error Handling

GMS-Zip uses structured error handling.

  • Bulk operations return errors.Join.
  • Specific errors are wrapped in *FileError for introspection.
Error Description
ErrFormat Not a valid ZIP archive (invalid signatures).
ErrPasswordMismatch Incorrect password or missing password.
ErrChecksum CRC-32 integrity check failed.
ErrInsecurePath Zip Slip detected: file path attempts to escape destination.
ErrDuplicateEntry A file with this name already exists in the archive.
ErrAlgorithm Compression method not supported (e.g., LZMA without plugin).
ErrFileNotFound Requested entry is missing. Wraps fs.ErrNotExist.
ErrFilenameTooLong Filename exceeds the ZIP limit of 65,535 bytes.
ErrResourceLimit Extraction exceeded defined limits.
ErrNotImplemented Code path is not implemented.

Code and Documentation Copyright © 1994-2026, Stephen Kapp and Reaper Technologies Limited. All Rights Reserved.