zip.js is a free, open source browsers & extensions project written in JavaScript and released under BSD-3-Clause. It has 3,894 GitHub stars, 547 forks and 1 open issues, and was last pushed 3 days ago. On this registry it ranks #68 of 133 tracked projects in Browsers & Extensions, with 5 head-to-head comparisons available.

What is zip.js?

zip.js is a BSD-3-Clause JavaScript library for compressing and decompressing zip files in browsers, Node.js, Deno and service workers, built for developers who need to read and write large archives in JavaScript without a native binary or a server round trip.

What it is

zip.js is an open-source JavaScript library that compresses and decompresses zip files, licensed BSD-3-Clause and published to npm as @zip.js/zip.js and to the JavaScript Registry as jsr:@zip-js/zip-js for Deno. Its topic list places it in the browser, Node.js, Deno and service worker environments. It exposes a reader and writer API — BlobReader, BlobWriter, TextReader, TextWriter, ZipReader and ZipWriter — alongside a filesystem-style facade called ZipFS, with documentation at https://gildas-lormeau.github.io/zip.js.

The problem it solves is archive work under JavaScript's memory and threading constraints. Large zip files cannot be held comfortably in a single buffer, so zip.js supports multi-core compression, native compression with compression streams, incremental writing, Zip64 archives larger than 4GB, split zip files and Deflate64 decompression. It also replaces the flat-list workflow, where an entry has to be searched out of an array, with ZipFS: entries are stored in a tree instead of a flat list, the reader and the writer are inferred from the type of the data, and an entry is reached from its path through find().

Key capabilities

  • Parallel, multi-core compression, with web workers named in the topic list (multi-core, multicore, web-worker).
  • Pluggable compression engines and native compression with compression streams, plus Deflate64 decompression on the read side.
  • Web Streams interop: zip content is written into a TransformStream and read back through new Response(zipFileStream.readable), matching the transform-stream and web-stream topics.
  • Zip64 support for archives larger than 4GB.
  • Split zip files (split-zip).
  • Data encryption, with both AES encryption and ZipCrypto listed among the topics.
  • ZipFS, the filesystem API: addText(), exportBlob(), importBlob() and find(), which resolves paths such as folder/hello.txt.

Who uses it and how

  • Browser applications that build an archive client-side and hand the result to the user as a Blob, with no server upload involved.
  • Service workers, per the service-worker topic, where compression runs off the main thread.
  • Node.js services and Deno scripts, the latter importing jsr:@zip-js/zip-js.
  • Teams working with archives too large for memory, using incremental writing, Zip64 and split files to append and divide entries instead of buffering the whole file.
  • Tooling that packages zip-based formats, with USDZ among the topics named.

Getting started

Install the npm package @zip.js/zip.js, or import jsr:@zip-js/zip-js in Deno. Documentation is at https://gildas-lormeau.github.io/zip.js and the demo at https://gildas-lormeau.github.io/zip-manager.

How it compares

The facts for this entry name no similar or competing tool, and no list of paid products that zip.js replaces is given. It therefore stands alone in this registry, and no side-by-side comparison can be drawn from the material provided.

When to use it — and when not to

zip.js is a library, not a service: whoever adopts it operates their own runtime, whether a browser page, a Node.js or Deno process, or a service worker, and no database, object storage, SMTP or hosted component appears in the facts. It is the wrong choice for anyone wanting a ready-made command-line archiver or a turnkey server application, since no CLI and no hosted option are described, only an embeddable API. Two honest cautions remain: the README tagline ends mid-sentence, and the topics list ZipCrypto next to AES, two schemes that are not equivalent in strength, so the encryption choice deserves review before it is relied on.

project readme (upstream, from github) — read inline

Introduction

zip.js is a JavaScript open-source library (BSD-3-Clause license) for compressing and decompressing zip files. It has been designed to handle large amounts of data. It supports notably multi-core compression, native compression with compression streams, pluggable compression engines, archives larger than 4GB with Zip64, split zip files, data encryption, incremental writing, and Deflate64 decompression.

Demo

See https://gildas-lormeau.github.io/zip-manager

Documentation

See here for more info: https://gildas-lormeau.github.io/zip.js/

Examples

Hello world

import {
  BlobReader,
  BlobWriter,
  TextReader,
  TextWriter,
  ZipReader,
  ZipWriter
} from "@zip.js/zip.js";
// "jsr:@zip-js/zip-js" for Deno

// ----
// Write the zip file
// ----

// Creates a BlobWriter object where the zip content will be written.
const zipFileWriter = new BlobWriter();
// Creates a TextReader object storing the text of the entry to add in the zip
// (i.e. "Hello world!").
const helloWorldReader = new TextReader("Hello world!");

// Creates a ZipWriter object writing data via `zipFileWriter`, adds the entry
// "hello.txt" containing the text "Hello world!" via `helloWorldReader`, and
// closes the writer.
const zipWriter = new ZipWriter(zipFileWriter);
await zipWriter.add("hello.txt", helloWorldReader);
await zipWriter.close();

// Retrieves the Blob object containing the zip content into `zipFileBlob`. It
// is also returned by zipWriter.close() for more convenience.
const zipFileBlob = await zipFileWriter.getData();

// ----
// Read the zip file
// ----

// Creates a BlobReader object used to read `zipFileBlob`.
const zipFileReader = new BlobReader(zipFileBlob);
// Creates a TextWriter object where the content of the first entry in the zip
// will be written.
const helloWorldWriter = new TextWriter();

// Creates a ZipReader object reading the zip content via `zipFileReader`,
// retrieves metadata (name, dates, etc.) of the first entry, retrieves its
// content via `helloWorldWriter`, and closes the reader.
const zipReader = new ZipReader(zipFileReader);
const firstEntry = (await zipReader.getEntries()).shift();
const helloWorldText = await firstEntry.getData(helloWorldWriter);
await zipReader.close();

// Displays "Hello world!".
console.log(helloWorldText);

Run the code on JSFiddle: https://jsfiddle.net/tm9fhvab/

Hello world with the filesystem API

The filesystem API stores the entries in a tree instead of a flat list. It needs a single import, it infers the Reader and the Writer from the type of the data, and it reaches an entry from its name instead of searching it in an array.

import { ZipFS } from "@zip.js/zip.js";
// "jsr:@zip-js/zip-js" for Deno

// ----
// Write the zip file
// ----

// Creates a ZipFS object and adds two entries to it. The name of an entry is a
// path, so the "folder" directory is created by the second call.
const zipFs = new ZipFS();
zipFs.addText("hello.txt", "Hello world!");
zipFs.addText("folder/hello.txt", "Hello world from a directory!");

// Retrieves the Blob object containing the zip content.
const zipFileBlob = await zipFs.exportBlob();

// ----
// Read the zip file
// ----

// Imports the zip content into a new ZipFS object, then retrieves the content
// of the entries from their full name.
const importedZipFs = new ZipFS();
await importedZipFs.importBlob(zipFileBlob);
const helloWorldText = await importedZipFs.find("hello.txt").getText();
const nestedText = await importedZipFs.find("folder/hello.txt").getText();

// Displays "Hello world!" and "Hello world from a directory!".
console.log(helloWorldText, nestedText);

Run the code on JSFiddle: https://jsfiddle.net/gcnret0x/

Hello world with Streams

import {
  BlobReader,
  ZipReader,
  ZipWriter
} from "@zip-js/zip-js";
// Prefix "@zip-js/zip-js" with "jsr:" for Deno

// ----
// Write the zip file
// ----

// Creates a TransformStream object, the zip content will be written in the
// `writable` property.
const zipFileStream = new TransformStream();
// Creates a Promise object resolved to the zip content returned as a Blob
// object retrieved from `zipFileStream.readable`.
const zipFileBlobPromise = new Response(zipFileStream.readable).blob();
// Creates a ReadableStream object storing the text of the entry to add in the
// zip (i.e. "Hello world!").
const helloWorldReadable = new Blob(["Hello world!"]).stream();

// Creates a ZipWriter object writing data into `zipFileStream.writable`, adds
// the entry "hello.txt" containing the text "Hello world!" retrieved from
// `helloWorldReadable`, and closes the writer.
const zipWriter = new ZipWriter(zipFileStream.writable);
await zipWriter.add("hello.txt", helloWorldReadable);
await zipWriter.close();

// Retrieves the Blob object containing the zip content into `zipFileBlob`.
const zipFileBlob = await zipFileBlobPromise;

// ----
// Read the zip file
// ----

// Creates a BlobReader object used to read `zipFileBlob`.
const zipFileReader = new BlobReader(zipFileBlob);
// Creates a TransformStream object, the content of the first entry in the zip
// will be written in the `writable` property.
const helloWorldStream = new TransformStream();
// Creates a Promise object resolved to the content of the first entry returned
// as text from `helloWorldStream.readable`.
const helloWorldTextPromise = new Response(helloWorldStream.readable).text();

// Creates a ZipReader object reading the zip content via `zipFileReader`,
// retrieves metadata (name, dates, etc.) of the first entry, retrieves its
// content into `helloWorldStream.writable`, and closes the reader.
const zipReader = new ZipReader(zipFileReader);
const firstEntry = (await zipReader.getEntries()).shift();
await firstEntry.getData(helloWorldStream.writable);
await zipReader.close();

// Displays "Hello world!".
const helloWorldText = await helloWorldTextPromise;
console.log(helloWorldText);

Run the code on JSFiddle: https://jsfiddle.net/aw3d6f4o/

Adding concurrently multiple entries in a zip file

import {
  BlobWriter,
  HttpReader,
  TextReader,
  ZipWriter,
} from "@zip-js/zip-js";
// Prefix "@zip-js/zip-js" with "jsr:" for Deno

const README_URL = "https://unpkg.com/@zip.js/zip.js/README.md";
getZipFileBlob()
  .then(downloadFile);

async function getZipFileBlob() {
  const zipWriter = new ZipWriter(new BlobWriter("application/zip"));
  await Promise.all([
    zipWriter.add("hello.txt", new TextReader("Hello world!")),
    zipWriter.add("README.md", new HttpReader(README_URL)),
  ]);
  return zipWriter.close();
}

function downloadFile(blob) {
  document.body.appendChild(Object.assign(document.createElement("a"), {
    download: "hello.zip",
    href: URL.createObjectURL(blob),
    textContent: "Download zip file",
  }));
}

Run the code on Plunker: https://plnkr.co/edit/4sVljNIpqSUE9HCA?preview

Custom web workers and compression engines

zip.js lets you create its web workers yourself by using the new Worker(new URL("./zip-worker.js", import.meta.url)) form. Bundlers like Vite, webpack and Rollup detect it and bundle the worker automatically. You can also delegate compression and decompression to a custom engine, e.g. fflate:

import { configure } from "@zip.js/zip.js/lib/zip-core-custom.js";

configure({
  createWorker: () => new Worker(
    new URL("./zip-worker.js", import.meta.url),
    { type: "module" }
  )
});
// zip-worker.js
import { initWorker } from "@zip.js/zip.js/worker";
import { CompressionStreamFallback, DecompressionStreamFallback } from "./fflate-streams.js";

initWorker({ CompressionStreamFallback, DecompressionStreamFallback });

See https://gildas-lormeau.github.io/zip.js/#custom-workers for a complete guide.

Tests

See https://github.com/gildas-lormeau/zip.js/tree/master/tests/all

Frequently asked questions

Is zip.js free to use?

zip.js is open source under the BSD-3-Clause licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does zip.js do?

JavaScript library to zip and unzip files supporting parallel compression, web streams, pluggable compression engines, zip64, split files, data encryption, and

What is zip.js written in?

zip.js is primarily written in JavaScript. Its source is publicly available at https://github.com/gildas-lormeau/zip.js, and it has 3,894 GitHub stars.