node-unzipper

A streaming zip extraction library for Node.js that supports random access to files on disk, in buffers, over HTTP, or on S3 without buffering the whole archive.

Library
npm
v0.12.5
473stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
74/100Good
Development Activity72
Maintenance72
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture74
Code Quality78
Innovation68
Learning Curve75

unzipper is a cross-platform, streaming zip-handling library for Node.js built entirely on the platform’s built-in zlib and stream modules, with no compiled native dependencies. It began as a fork of node-unzip and now offers two complementary APIs: a legacy streaming Parse/Extract interface that processes a zip file sequentially as it arrives, and a newer Open interface that reads the zip’s central directory first and then grants random access to individual files inside it.

The Open methods (Open.file, Open.buffer, Open.url, Open.s3, Open.s3_v3, Open.custom) are the more distinctive part of the library: each accepts a source capable of returning byte ranges and a total size, then locates the end-of-central-directory record using only the tail bytes of the archive. This lets a caller extract a single file out of a multi-hundred-megabyte zip hosted remotely by issuing HTTP range requests or S3 range GETs, never downloading the full archive. The legacy Parse path remains useful for straightforward local extraction and for piping zip entries into transform streams.

Because it’s a long-lived project (first released in 2016, still receiving regular commits), it has accumulated support for edge cases like zip64 extended fields, CRX (Chrome extension) headers, password-encrypted entries via Decrypt.js, and non-UTF8 filename encodings from legacy DOS/Windows zip tools.

What You Get

  • Sequential streaming API (Parse, ParseOne, Extract) for piping a zip file’s contents through Node streams as they arrive
  • Random-access Open API (Open.file, Open.buffer, Open.url, Open.s3, Open.s3_v3, Open.custom) that reads only the central directory plus the requested file’s bytes
  • Support for password-protected/encrypted zip entries via a built-in decryption module
  • Handling for zip64 extended fields, CRX (Chrome extension) archive headers, and non-Unicode legacy filename encodings
  • A pluggable custom-source interface so any byte-range-capable backend (e.g. Google Cloud Storage) can be wired into the Open API
  • Dual ESM/CommonJS build output, so it can be required or imported depending on the consumer’s module system

Common Use Cases

  • Extracting a single known file out of a very large zip archive hosted remotely, without downloading the whole thing
  • Streaming-unzipping an uploaded zip file directly to disk or to another stream-based pipeline (e.g. an ETL transform)
  • Reading zip archives stored in S3 or S3-compatible object storage using HTTP range requests
  • Parsing zip files produced by legacy DOS/Windows tools that use non-UTF8 filename encoding
  • Unpacking Chrome extension (.crx) packages, which are zip files with an extra header

Under The Hood

Architecture unzipper splits cleanly into two independent pipelines that share low-level primitives. The legacy path (lib/parse.js) implements a Parser as a Node Duplex stream that reads local file header signatures (0x04034b50), central directory signatures (0x02014b50), and the end-of-central-directory signature (0x06054b50) off a custom PullStream (lib/PullStream.js), emitting entry events or pushing parsed entries downstream when piped. The Open path (lib/Open/index.js + lib/Open/directory.js) instead wraps an abstract source object exposing stream(offset, length) and size(), reads only the tail of the archive to locate the end-of-central-directory record (configurable via a tailSize option, default 80 bytes), and returns a files array whose entries expose stream()/buffer() for on-demand random access — this is what lets Open.url and Open.s3 avoid downloading the entire archive. PullStream itself is the shared abstraction underneath both paths: a Duplex that buffers incoming bytes and lets callers pull(eof) either a fixed byte count or up-to-a-signature-match, which both the sequential parser and the central-directory reader build on. Swapping the core PullStream buffering strategy would ripple through both APIs since neither has an alternate low-level read path.

Tech Stack The library ships as native ESM ("type": "module", index.js) with a parallel CommonJS build (index.cjs, generated at publish time via a Babel-based build-commonjs script and a small scripts/create-commonjs-package-json.cjs helper) so it’s consumable from either module system. Zip inflation itself uses Node’s built-in zlib, and file-system access goes through graceful-fs rather than the raw fs module to better tolerate EMFILE/ENFILE errors on busy systems. Runtime dependencies are intentionally small: bluebird (promise utilities in older code paths), duplexer2 (composing duplex streams), fs-extra, graceful-fs, and node-int64 (for zip64 64-bit offsets that exceed JS’s safe integer range). Optional integrations — request for Open.url, aws-sdk/@aws-sdk/client-s3 for Open.s3/Open.s3_v3 — are consumer-supplied peer-style dependencies rather than bundled ones, so applications only pull them in if they use those specific Open methods. CI runs on GitHub Actions with separate test.yml, coverage.yml, and publish.yml workflows.

Code Quality Testing uses tap with coverage thresholds enforced in package.json scripts (--lines=90 --functions=85 --statements=90 --branches=80), and the suite is run twice — once against the native ESM build (test-esm) and once against a Babel-transpiled CommonJS build (test-esm-transpiled) plus a dedicated test-commonjs suite — to guard both distribution targets. The test/ directory covers a wide range of scenarios beyond the happy path: zip64 archives, CRX headers, broken/corrupt zips, chunk-boundary edge cases, encrypted files, S3 (both SDK v2 and v3 clients), custom sources, and zip-slip path-traversal protection (zipSlipSiblingPrefix.js). ESLint is configured with a small custom ruleset (no-var, prefer-const, enforced semicolons/indentation) on top of @eslint/js recommended rules. Error handling is mostly done through stream error events and rejected promises rather than typed exceptions (there’s no TypeScript here, and no static types), and some internal comments (e.g. in PullStream.js) note inherited code whose original rationale wasn’t fully understood by later maintainers — a sign of accumulated legacy behavior rather than a from-scratch design.

API Design The library’s two APIs are pitched at different levels of ergonomics. The streaming Parse/Extract API mirrors Node’s own stream idioms closely (.pipe(), entry events, .autodrain() to discard unwanted entries, async-iterator support via for await), which keeps the learning curve low for anyone already comfortable with Node streams — though it does require callers to remember to drain or consume every entry or the stream stalls. The Open API trades that familiarity for a promise-based random-access model (await unzipper.Open.file(...), then directory.files[0].stream()/.buffer()) that’s more convenient for one-off extraction but requires understanding a different mental model (central directory vs. sequential parse). Documentation is thorough for a project this size — the README walks through every open method, S3 v2 vs v3 usage, custom source implementation, and legacy-encoding handling with runnable examples — though some newer usage (e.g. Open.custom) is documented only by example rather than a full API reference.

Used by 12 apps in this directory

Rust
67%
MIT

Bun

Developer Tools

95,895

An all-in-one JavaScript and TypeScript toolkit — one Rust-and-JavaScriptCore binary that replaces Node.js, npm, a bundler, and a test runner with faster equivalents.

View details
92
Repo Health
91
Technical
64
Dependency
Built with
Rust67%
C++19%
Updated yesterday
TypeScript
51%
Other

Jan

AI Assistants

44,366

Run LLMs 100% locally with full privacy, or connect to cloud AI — your machine, your data, your control.

View details
89
Repo Health
81
Technical
65
Dependency
Built with
TypeScript51%
Rust46%
Updated 3 days ago
TypeScript
88%
Apache 2.0

Medplum

Developer Tools · Databases · Authentication

2,657

An open-source, FHIR-native healthcare platform that gives developers a compliant backend, authentication, a React component library, and serverless bots to build clinical applications in weeks instead of years.

View details
93
Repo Health
90
Technical
72
Dependency
Built with
TypeScript88%
MDX10%
Updated yesterday
TypeScript
97%
Other

nango

Developer Tools · Automation · Authentication

11,746

Build product integrations with AI using 800+ APIs — auth, proxy, and TypeScript functions on production-grade infrastructure.

View details
93
Repo Health
85
Technical
68
Dependency
Built with
TypeScript97%
Updated 3 days ago
TypeScript
88%
AGPL 3.0

OpenPanel

Analytics

6,884

Open-source Mixpanel alternative with session replay, MCP integration, and privacy-first product analytics you fully control.

View details
74
Repo Health
74
Technical
68
Dependency
Built with
TypeScript88%
Updated 3 days ago
JavaScript
60%
MIT

OpenWhispr

Productivity · AI Assistants

7,381

Privacy-first, cross-platform voice-to-text with local AI and cloud options

View details
86
Repo Health
80
Technical
72
Dependency
Built with
JavaScript60%
TypeScript35%
Updated 2 days ago
TypeScript
96%
Other

superglue

AI Agents · Data Engineering · Developer Tools

2,056

superglue is an AI-agent-driven integration engine that turns plain-English descriptions of enterprise systems into production-grade API tools, ERP/CRM connectors, and data pipelines — self-hosted or cloud, Y Combinator-backed (W25).

View details
54
Repo Health
79
Technical
71
Dependency
Built with
TypeScript96%
Updated 2 weeks ago
Go
90%
BSD 3

tau

Devops

5,135

Open-source, Git-native platform-as-a-service for building, deploying, and scaling fullstack apps on your own infrastructure with no DevOps required.

View details
82
Repo Health
82
Technical
65
Dependency
Built with
Go90%
Updated 3 weeks ago
TypeScript
99%
Other

Teable

Databases · No Code Platforms

21,759

A no-code PostgreSQL database with spreadsheet UX, real-time collaboration, and native AI agents — built for teams that outgrow Airtable.

View details
79
Repo Health
76
Technical
63
Dependency
Built with
TypeScript99%
Updated today

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