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

@greggman/zipup

v0.0.2

Published

small modern zip library for JavaScript

Readme

zipup.js

Simple modern, small, zero dependency zip library for browser and node based JavaScript

Build and Deploy [Live Tests]

Most data is stored in blob so theoretically the browser or node can virtualize the storage.

Example Usage:

import { Zip } from '@greggman/zipup';

const zip = new Zip();
zip.addFile('foo.txt', someString);
zip.addFile('bar.png', someArrayBuffer);
zip.addFile('folder/moo.mp4', someArrayBufferView);
zip.addFile('folder/stuff.bin', someBlob);
const blob = await zip.finalize(comment?: string);

after which you could offer it to the user to download

const saveBlob = (function() {
  const a = document.createElement('a');
  document.body.appendChild(a);
  a.style.display = 'none';
  return function saveData(blob, fileName) {
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = fileName;
    a.click();
  };
}());

saveBlob(blob, 'your-data.zip');

API

class Zip {
  constructor(options: { platform?: Platform });
  async addFile(pathOrInfo: string | EntryInfo, string | ArrayBuffer | ArrayBufferView | Blob): Promise<void>;
  addFolder(pathOrInfo: string | EntryInfo): ZipFolder;
  async finalize(comment?: string): Promise<Blob>;
};

class EntryInfo {
  name: string,                     // name of entry
  comment: string,                  // the comment for this entry
  lastModDate: Date,                // a Date
  attributes: number,               // platform specific attributes
};

class ZipFolder {
  async addFile(meta: string | EntryInfo, string | ArrayBuffer | ArrayBufferView | Blob): Promise<void>;
  addFolder(meta: string | EntryInfo): ZipFolder;  
};

type Platform = 'windows' | 'linux' | 'macos' | 'unix';

As you can see above you can pass either just a path, or an object with more meta data

zip.addFile('hello.txt', someString);
zip.addFile({
  name: 'readme.txt',
  comment?: 'the readme file',
  lastModData?: new Date(),  // or any date
}, content)

addFile is asynchronous. You do not have to wait as finalize will automatically wait but addFile does return a promise if you want to throttle (🤷‍♂️).

You can add a file to a folder either by including it in the name

zip.addFile('folder/file.bin', ...);

or by creating a folder

const folder = zip.addFolder('folder');
folder.addFile('file.bin');

Why?

Most of the other libraries are old and crufty. The browser itself now supports compression and so does node.js so why not just use those. Example: JSZip is 754k. zipup is < 3k (gzipped). Yes, that's not a completely fair comparison. zipup has the functionality I need. I don't need the other 751k of stuff. Nor do I need 13 dependencies.

Note: the library uses CompressionStream. Use a polyfill if you're supporting old stuff.

Unzip

Use unzipit.

Attributes

AFAICT it's not common to use attributes in zip files. Attributes in zip files are platform specific and to be honest, I have no idea what all the various tools do as there are too many. Effectively, if you want to set permissions you should choose a platform when you create the zip file and then use the appropriate permissions.

import {Zip, DosAttributes, UnixPermissions} from 'zipup';

const dosZip = new Zip({platform: 'windows'});
dosZip.addFile({
  name: 'foo.txt',
  attributes: DosAttributes.READ_ONLY,
});
const dosBlob = await dosZip.finalize();

const unixZip = new Zip({platform: 'unix'});
unixZip.addFile({
  name: 'foo.txt',
  attributes: UnixPermissions.FILE_755, // or 0o755
});
const unixZip = await dosZip.finalize();

Testing

Use npm test to run the tests from the command line.

Live Browser Tests

https://greggman.github.io/zipup/test/

License

MIT