These libraries provide tools for creating, reading, and manipulating ZIP archives in JavaScript environments. adm-zip, archiver, jszip, node-zip, zip-a-folder, and zip-lib each offer different approaches to compression, ranging from synchronous file manipulation to streaming pipelines and browser-compatible async APIs. Developers choose between them based on whether they need server-side streaming, client-side compatibility, or simple synchronous access to zip contents.
Managing ZIP files is a common requirement in web development, whether you are generating reports on a server or letting users download assets in a browser. The ecosystem offers several tools like adm-zip, archiver, jszip, node-zip, zip-a-folder, and zip-lib, but they solve different problems. Some focus on streaming large files, while others prioritize browser compatibility or synchronous simplicity. Let's compare how they handle real-world tasks.
archiver is built for streaming.
// archiver: Stream to file
const archiver = require('archiver');
const output = fs.createWriteStream('archive.zip');
const archive = archiver('zip');
archive.pipe(output);
archive.file('file1.txt', { name: 'file1.txt' });
archive.finalize();
adm-zip works in memory synchronously.
// adm-zip: Write to file synchronously
const AdmZip = require('adm-zip');
const zip = new AdmZip();
zip.addLocalFile('file1.txt');
zip.writeZip('archive.zip');
jszip works in memory asynchronously.
// jszip: Generate async buffer
const JSZip = require('jszip');
const zip = new JSZip();
zip.file('file1.txt', 'content');
const content = await zip.generateAsync({ type: 'nodebuffer' });
fs.writeFileSync('archive.zip', content);
node-zip creates archives synchronously.
// node-zip: Create from string
const zip = require('node-zip');
const z = new zip();
z.file('file1.txt', 'content');
const data = z.generate({ base64: false });
fs.writeFileSync('archive.zip', data, 'binary');
zip-a-folder targets directory archiving.
// zip-a-folder: Zip entire folder
const zipFolder = require('zip-a-folder');
await zipFolder.zip('./source-folder', './archive.zip');
zip-lib offers a direct API for compression.
adm-zip but with a different method structure.// zip-lib: Zip files
const zip = require('zip-lib');
await zip.archive(['file1.txt'], 'archive.zip');
adm-zip extracts files synchronously.
// adm-zip: Extract all
const zip = new AdmZip('archive.zip');
zip.extractAllTo('./destination', true);
archiver does not handle extraction.
unzipper for reading.// archiver: N/A (Creation only)
// Developers typically pair archiver with unzipper for extraction
jszip extracts data asynchronously.
// jszip: Read content async
const JSZip = require('jszip');
const zip = await JSZip.loadAsync(fs.readFileSync('archive.zip'));
const file = await zip.file('file1.txt').async('string');
node-zip reads data synchronously.
// node-zip: Read entries
const z = new zip(fs.readFileSync('archive.zip'));
const content = z.files['file1.txt'].data;
zip-a-folder does not handle extraction.
adm-zip or jszip if you need to unzip.// zip-a-folder: N/A (Creation only)
// No built-in extraction methods provided
zip-lib supports extraction asynchronously.
extract function for unpacking archives.// zip-lib: Extract files
const zip = require('zip-lib');
await zip.extract('archive.zip', './destination');
adm-zip runs on Node.js only.
// adm-zip: Node.js only
const AdmZip = require('adm-zip'); // Fails in browser
archiver runs on Node.js only.
// archiver: Node.js only
const archiver = require('archiver'); // Fails in browser
jszip runs everywhere.
// jszip: Universal
const JSZip = require('jszip'); // Works in Node and Browser
node-zip runs on Node.js only.
// node-zip: Node.js only
const zip = require('node-zip'); // Fails in browser
zip-a-folder runs on Node.js only.
// zip-a-folder: Node.js only
const zipFolder = require('zip-a-folder'); // Fails in browser
zip-lib runs on Node.js only.
// zip-lib: Node.js only
const zip = require('zip-lib'); // Fails in browser
adm-zip is stable and widely used.
archiver is actively maintained.
jszip is actively maintained.
node-zip is deprecated.
adm-zip or archiver.zip-a-folder has limited maintenance.
zip-lib has moderate maintenance.
archiver or jszip.| Package | Environment | API Style | Streaming | Extraction | Status |
|---|---|---|---|---|---|
adm-zip | Node | Sync | ā | ā | Stable |
archiver | Node | Stream | ā | ā | Stable |
jszip | Both | Async | ā | ā | Stable |
node-zip | Node | Sync | ā | ā | Deprecated |
zip-a-folder | Node | Async | ā | ā | Niche |
zip-lib | Node | Async | ā | ā | Moderate |
archiver is the top pick for backend servers š„ļø ā use it when you need to stream large files to a user without crashing your memory. It pairs well with Express or similar frameworks for download endpoints.
jszip is the top pick for frontend apps š ā use it when you need to create or read ZIPs directly in the browser. It is the only robust choice that works universally.
adm-zip is the top pick for simple scripts š ā use it for quick build tools or local CLI commands where streaming is not needed and simplicity is key.
Avoid node-zip š« ā it is outdated and lacks the features of modern alternatives. Stick to the actively maintained options for security and reliability.
Choose adm-zip if you need a pure JavaScript solution for Node.js that works synchronously with local files. It is ideal for scripts that need to quickly read or extract small to medium-sized archives without managing streams. Avoid it for large files or server responses where memory usage and blocking the event loop are concerns.
Choose archiver if you are building a server-side application that needs to stream ZIP files directly to a response or disk. It handles large datasets efficiently by processing data in chunks rather than loading everything into memory. It is the standard choice for backend APIs that generate downloadable archives on the fly.
Choose jszip if your code needs to run in both the browser and Node.js environments. It offers a flexible async API that works well for manipulating archive contents in memory before saving or downloading. It is perfect for frontend tools that let users upload, modify, and download ZIP files without server interaction.
Avoid node-zip for new projects as it is largely considered deprecated and unmaintained compared to modern alternatives. It was historically used for basic ZIP creation but lacks the streaming capabilities and active support of archiver or adm-zip. Evaluate adm-zip or archiver instead for better long-term stability.
Choose zip-a-folder if you have a very specific need to recursively zip an entire directory structure with minimal configuration. It acts as a utility wrapper that simplifies the process of archiving folders without writing boilerplate code. Use it for quick scripts where fine-grained control over the archive stream is not required.
Choose zip-lib if you need a lightweight library focused on specific compression tasks in Node.js. It provides a straightforward API for zipping and unzipping files but has a smaller ecosystem than archiver or jszip. Verify its maintenance status before adopting it for critical production infrastructure.
ADM-ZIP is a pure JavaScript implementation for zip data compression for NodeJS.
With npm do:
$ npm install adm-zip
Electron file system support described below.
The library allows you to:
There are no other nodeJS libraries that ADM-ZIP is dependent of
var AdmZip = require("adm-zip");
// reading archives
var zip = new AdmZip("./my_file.zip");
var password = "1234567890";
var zipEntries = zip.getEntries(); // an array of ZipEntry records - add password parameter if entries are password protected
zipEntries.forEach(function (zipEntry) {
console.log(zipEntry.toString()); // outputs zip entries information
if (zipEntry.entryName == "my_file.txt") {
console.log(zipEntry.getData().toString("utf8"));
}
});
// outputs the content of some_folder/my_file.txt
console.log(zip.readAsText("some_folder/my_file.txt"));
// extracts the specified file to the specified location
zip.extractEntryTo(/*entry name*/ "some_folder/my_file.txt", /*target path*/ "/home/me/tempfolder", /*maintainEntryPath*/ false, /*overwrite*/ true);
// extracts everything
zip.extractAllTo(/*target path*/ "/home/me/zipcontent/", /*overwrite*/ true);
// creating archives
var zip = new AdmZip();
// add file directly
var content = "inner content of the file";
zip.addFile("test.txt", Buffer.from(content, "utf8"), "entry comment goes here");
// add local file
zip.addLocalFile("/home/me/some_picture.png");
// get everything as a buffer
var willSendthis = zip.toBuffer();
// or write everything to disk
zip.writeZip(/*target file name*/ "/home/me/files.zip");
// ... more examples in the wiki
For more detailed information please check out the wiki.
ADM-ZIP has supported electron original-fs for years without any user interractions but it causes problem with bundlers like rollup etc. For continuing support original-fs or any other custom file system module. There is possible specify your module by fs option in ADM-ZIP constructor.
Example:
const AdmZip = require("adm-zip");
const OriginalFs = require("original-fs");
// reading archives
const zip = new AdmZip("./my_file.zip", { fs: OriginalFs });
.
.
.