npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yuhere/js-zip

v1.0.0

Published

utility library for reading and writing zip files in browser.

Readme

js-zip

js-zip is a JavaScript library for creating and reading .zip files in the browser.

This library is forked from the version of https://github.com/gildas-lormeau/zip.js/tree/v2.8.26

Examples

Hello world

import {
  BlobReader,
  BlobWriter,
  TextReader,
  TextWriter,
  ZipReader,
  ZipWriter
} from "@yuhere/js-zip";

// ----
// 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);

Hello world with Streams

import {
  BlobReader,
  ZipReader,
  ZipWriter
} from "@yuhere/js-zip";

// ----
// 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);

Modifications

  1. Removed the Web Worker approach (some residual code remains, to be cleaned up);
  2. Added support for batched read/write of zip files, suitable for handling large files;

Reference

https://github.com/gildas-lormeau/zip.js/tree/master/WebContent/tests
var {zip} = require("zipjs");

function zipBlob(fn, blob, callback, onerror) {
  zip.createWriter(new zip.BlobWriter("application/zip"),
    function (zipWriter) {
      zipWriter.add(fn, new zip.BlobReader(blob), function () {
        zipWriter.close(callback);
      });
    }, (onerror || function def_onerror(message) {
      console.error(message);
    }));
}

function unzipBlob(fn, blob, callback, onerror) {
  zip.createReader(new zip.BlobReader(blob),
    function (zipReader) {
      zipReader.getEntries(function (entries) {
        for (var i = 0; i < entries.length; i++) {
          var obj = entries[i];
          if (!obj.directory && obj.filename === fn) {
            obj.getData(new zip.BlobWriter("text/plain"), function (data) {
              zipReader.close();
              callback(data);
              return;
            });
          }
        }
        callback();  // not found the file
      });
    }, (onerror || function def_onerror(message) {
      console.error(message);
    })
  );
}

One-shot read/write example (callback)

// Read a specific zip entry by name
unzipBlob(entryName, zippedBlob, function (unzippedBlob) {
    if (unzippedBlob !== undefined) {
        ..... unzippedBlob
        var reader = new FileReader();
        reader.readAsText(unzippedBlob);
    }
}, function (err) { // on error handler
    console.error(err);
});

// Write a zip file
zipEntries.push({fn: "data1.json", blob: new Blob([JSON.stringify({record: data}, null, 2)], {type: 'text/plain;charset=utf-8'})});
zipEntries.push({fn: "data2.json", blob: new Blob([JSON.stringify({record: data}, null, 2)], {type: 'text/plain;charset=utf-8'})});
zipBlob(zipEntries, function (zippedBlob) {
    saveAs(zippedBlob, file_name_idx + ".dat.zip");
});

Batched read/write example

async function(zipFileBlob) {
    const reader = await createReader(zipFileBlob);
    // createReader, getFileEntries, getEntryTextData, closeReader
    const entries = await getFileEntries(reader, (entry, idx) => {
        return /cache_exp_\d+\.json/gi.exec(entry.filename)
    });
    //
    const stat = {count: 0};
    //
    for (let i = 0;i < entries.length;i++) {
        let blob = await getEntryData(reader, entries[i]);
        let list = await blob2json(blob);
        // blob is the data from the zipEntry
        // process it as needed...
    }
    console.log("...bulkPut...end...");
    await closeReader(reader);
};

async function(name, fn, callback) {
    // createWriter, addToZip, closeWriter
    const zipWriter = await createWriter();
    ...
    //
    const irs = await cache_export_i(name, db, total, SIZE);
    for (let ii = 0, {done, value} = await irs.next();!done;ii++, {done, value} = await irs.next()) {
        // Get data batch by batch in the loop
        typeof(callback)==="function" && callback("in-progress", ii * SIZE + value.length, total);
        // Add each batch to the zip incrementally
        await addToZip(zipWriter, {fn: "fcache_exp_" + ii + ".json", blob: new Blob([JSON.stringify(value, null, 2)])} )
    }
    // Finally get the zipped blob
    const zippedBlob = await closeWriter(zipWriter);
    typeof(callback)==="function" && callback("done", fn);
    return saveAs(zippedBlob, fn);
};