extract-zip vs adm-zip vs node-unzip-2 vs node-zip vs unzipper vs yauzl
Node.js Libraries for ZIP File Handling
extract-zipadm-zipnode-unzip-2node-zipunzipperyauzlSimilar Packages:

Node.js Libraries for ZIP File Handling

adm-zip, extract-zip, node-unzip-2, node-zip, unzipper, and yauzl are Node.js libraries for working with ZIP archive files. They provide varying levels of support for reading, writing, extracting, and streaming ZIP content. Some focus exclusively on extraction, others support full archive manipulation, and a few are designed for in-memory operations only. These tools are commonly used in backend services for handling file uploads, generating downloadable bundles, or processing compressed data feeds.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
extract-zip20,574,707397-556 years agoBSD-2-Clause
adm-zip02,161121 kB1482 years agoMIT
node-unzip-2044-217 years agoMIT
node-zip0217-2011 years ago-
unzipper047556.6 kB862 years agoMIT
yauzl080196.1 kB189 days agoMIT

Handling ZIP Files in Node.js: A Deep Dive into Popular Libraries

When you need to work with ZIP archives in a Node.js environment β€” whether extracting user-uploaded files, packaging build artifacts, or processing compressed data streams β€” choosing the right library matters. The ecosystem offers several options, each with distinct trade-offs in terms of streaming support, memory usage, API design, and maintenance status. Let’s examine adm-zip, extract-zip, node-unzip-2, node-zip, unzipper, and yauzl through the lens of real-world engineering constraints.

πŸ“¦ Core Capabilities: What Each Library Actually Does

adm-zip provides full read/write support for ZIP files using synchronous and asynchronous APIs. It loads entire archives into memory, which simplifies usage but limits scalability.

// adm-zip: extract all entries to disk
const AdmZip = require('adm-zip');
const zip = new AdmZip('./archive.zip');
zip.extractAllTo('./output/');

// adm-zip: create a new ZIP
const zip2 = new AdmZip();
zip2.addLocalFile('./file.txt');
zip2.writeZip('./new.zip');

extract-zip is purpose-built for one task: extracting ZIP files to disk. It wraps yauzl under the hood and only supports extraction (no creation or in-memory reading).

// extract-zip: simple extraction
const extract = require('extract-zip');
await extract('./archive.zip', { dir: './output/' });

node-unzip-2 is a fork of the deprecated node-unzip package. It offers streaming extraction via Node.js streams but hasn’t seen active maintenance in recent years.

// node-unzip-2: stream-based extraction
const fs = require('fs');
const unzip = require('node-unzip-2');

fs.createReadStream('./archive.zip')
  .pipe(unzip.Extract({ path: './output/' }))
  .on('close', () => console.log('Done'));

node-zip is a wrapper around JSZip, designed primarily for in-browser use but usable in Node.js via buffer. It doesn't interact with the filesystem directly and requires manual buffer handling.

// node-zip: in-memory only
const Zip = require('node-zip');
const zip = new Zip();
zip.file('hello.txt', 'Hello World!');
const data = zip.generate({ type: 'nodebuffer' }); // Buffer

unzipper supports both streaming and buffered operations for reading ZIP files. It can extract to disk or parse entries in memory, and it handles large files efficiently by avoiding full archive loading.

// unzipper: streaming extraction
const fs = require('fs');
const unzipper = require('unzipper');

fs.createReadStream('./archive.zip')
  .pipe(unzipper.Extract({ path: './output/' }))
  .on('close', () => console.log('Extracted'));

// unzipper: parse entries without extraction
fs.createReadStream('./archive.zip')
  .pipe(unzipper.Parse())
  .on('entry', (entry) => {
    console.log(entry.path);
    entry.autodrain(); // discard content
  });

yauzl ("yet another unzip library") is a low-level, streaming-first library focused exclusively on reading ZIP files. It does not support writing ZIPs or extracting to disk directly β€” you must handle file system operations yourself.

// yauzl: manual entry processing
const yauzl = require('yauzl');

yauzl.open('./archive.zip', (err, zipfile) => {
  zipfile.on('entry', (entry) => {
    zipfile.openReadStream(entry, (err, readStream) => {
      readStream.on('end', () => zipfile.readEntry());
      readStream.pipe(process.stdout); // or write to file
    });
    if (!zipfile.isOpen) zipfile.readEntry();
  });
  zipfile.readEntry();
});

πŸ’Ύ Memory vs Streaming: The Critical Trade-off

If your application processes small ZIP files (<50MB), libraries like adm-zip or node-zip are convenient because they abstract away streaming complexity. However, they load the entire archive into memory, which becomes problematic with larger files.

For server applications handling user uploads or large datasets, streaming is essential. unzipper and yauzl excel here:

  • yauzl gives you fine-grained control but requires more boilerplate.
  • unzipper provides higher-level abstractions (like Extract) while still being memory-efficient.

extract-zip inherits yauzl’s streaming behavior but hides the complexity behind a promise-based API β€” ideal when you just need to dump contents to disk.

node-unzip-2 also streams, but its outdated dependencies and lack of recent updates raise reliability concerns for production use.

πŸ”§ Write Support: Do You Need to Create ZIPs?

Only three packages support creating ZIP archives:

  • adm-zip: Full read/write with filesystem integration.
  • node-zip: In-memory only (via JSZip), no direct file I/O.
  • unzipper: Read-only β€” despite the name, it cannot create ZIPs.

If you need to generate ZIP files from buffers or streams, adm-zip is the most straightforward choice in Node.js. For browser-compatible generation that also works in Node, node-zip (JSZip) is viable but requires manual file writing.

⚠️ Maintenance and Deprecation Status

Based on official npm and GitHub sources:

  • node-unzip-2 is a community fork of the abandoned node-unzip. While functional, it lacks active maintenance and modern security updates. Avoid in new projects.
  • node-zip is a thin wrapper over JSZip, which is actively maintained, but the wrapper itself sees infrequent updates. Use only if you specifically need JSZip compatibility.
  • adm-zip, extract-zip, unzipper, and yauzl are all actively maintained as of 2024, with recent releases addressing security and compatibility.

πŸ› οΈ Real-World Selection Guide

Scenario 1: Extract user-uploaded ZIPs to disk

  • βœ… Best: extract-zip β€” simple, secure, streaming, and purpose-built.
  • Alternative: unzipper if you need more control over entry filtering.
// Preferred: extract-zip
await extract('./upload.zip', { dir: './uploads/extracted' });

Scenario 2: Process large ZIPs without exhausting memory

  • βœ… Best: yauzl or unzipper.
  • Choose yauzl for maximum control; unzipper for simpler syntax.
// With unzipper
fs.createReadStream('large.zip')
  .pipe(unzipper.Parse())
  .on('entry', entry => {
    if (entry.path.endsWith('.json')) {
      entry.pipe(fs.createWriteStream(`./data/${entry.path}`));
    } else {
      entry.autodrain();
    }
  });

Scenario 3: Generate ZIP files from application data

  • βœ… Best: adm-zip β€” native filesystem support and intuitive API.
  • Avoid node-zip unless you’re already using JSZip in the browser.
// With adm-zip
const zip = new AdmZip();
zip.addFile('config.json', Buffer.from(JSON.stringify(config)));
zip.writeZip('./bundle.zip');

Scenario 4: Parse ZIP metadata without extraction

  • βœ… Best: yauzl β€” lightweight and fast for listing entries.
// With yauzl
yauzl.open('archive.zip', (err, zipfile) => {
  zipfile.on('entry', entry => console.log(entry.fileName));
  zipfile.readEntry();
});

πŸ“Š Summary Table

PackageRead ZIPWrite ZIPStream SupportExtract to DiskIn-Memory OnlyActively Maintained
adm-zipβœ…βœ…βŒβœ…βŒβœ…
extract-zipβœ…βŒβœ… (via yauzl)βœ…βŒβœ…
node-unzip-2βœ…βŒβœ…βœ…βŒβŒ (avoid)
node-zipβœ…βœ…βŒβŒβœ…βš οΈ (wrapper only)
unzipperβœ…βŒβœ…βœ…βœ…βœ…
yauzlβœ…βŒβœ…βŒ (manual)βœ…βœ…

πŸ’‘ Final Recommendation

  • For extraction only: Use extract-zip β€” it’s safe, simple, and efficient.
  • For large-file processing: Choose unzipper for balance or yauzl for precision.
  • For ZIP creation: Stick with adm-zip unless you have cross-environment (browser + Node) requirements.
  • Avoid node-unzip-2 in new codebases due to maintenance risks.

Remember: ZIP handling often involves untrusted input. Always validate file paths during extraction to prevent directory traversal attacks β€” libraries like extract-zip and unzipper include built-in protections, but lower-level tools like yauzl leave this to you.

How to Choose: extract-zip vs adm-zip vs node-unzip-2 vs node-zip vs unzipper vs yauzl

  • extract-zip:

    Choose extract-zip when your only requirement is to safely extract ZIP files to disk. It’s built on yauzl, supports streaming, includes path sanitization to prevent directory traversal, and offers a clean promise-based API. This is the go-to choice for handling user-uploaded ZIPs in web applications where security and simplicity matter most.

  • adm-zip:

    Choose adm-zip when you need a simple, all-in-one solution for both reading and writing ZIP files with direct filesystem integration. It’s ideal for small to medium archives where loading the entire file into memory is acceptable, such as generating report bundles or processing trusted internal files. Avoid it for large files or untrusted inputs due to its synchronous defaults and memory usage.

  • node-unzip-2:

    Avoid node-unzip-2 in new projects. It’s a community-maintained fork of the deprecated node-unzip and lacks active development or security updates. While it supports streaming extraction, modern alternatives like unzipper or extract-zip offer better reliability, features, and maintenance. Only consider it if you’re maintaining legacy code that already depends on it.

  • node-zip:

    Choose node-zip only if you need JSZip compatibility between browser and Node.js environments. It operates entirely in memory and doesn’t interact with the filesystem directly, so you’ll need to handle file reads/writes manually. It’s suitable for client-side-like ZIP generation in Node scripts but less practical for typical server-side file processing tasks.

  • unzipper:

    Choose unzipper when you need flexible, streaming-based ZIP parsing with support for both disk extraction and in-memory entry processing. It handles large files efficiently, provides high-level utilities like Extract, and allows fine-grained control via Parse. Ideal for server applications that process untrusted or large archives without excessive memory consumption.

  • yauzl:

    Choose yauzl when you require a minimal, low-level, streaming-first library for reading ZIP files. It gives you full control over entry processing but requires manual implementation of file writing and security checks like path validation. Best suited for performance-critical or specialized use cases where you need to inspect or filter archive contents without full extraction.

README for extract-zip

extract-zip

Unzip written in pure JavaScript. Extracts a zip into a directory. Available as a library or a command line program.

Uses the yauzl ZIP parser.

NPM Uses JS Standard Style Build Status

Installation

Make sure you have Node 10 or greater installed.

Get the library:

npm install extract-zip --save

Install the command line program:

npm install extract-zip -g

JS API

const extract = require('extract-zip')

async function main () {
  try {
    await extract(source, { dir: target })
    console.log('Extraction complete')
  } catch (err) {
    // handle any errors
  }
}

Options

  • dir (required) - the path to the directory where the extracted files are written
  • defaultDirMode - integer - Directory Mode (permissions), defaults to 0o755
  • defaultFileMode - integer - File Mode (permissions), defaults to 0o644
  • onEntry - function - if present, will be called with (entry, zipfile), entry is every entry from the zip file forwarded from the entry event from yauzl. zipfile is the yauzl instance

Default modes are only used if no permissions are set in the zip file.

CLI Usage

extract-zip foo.zip <targetDirectory>

If not specified, targetDirectory will default to process.cwd().