Skip to content

About

Isomorphic, native (de)compression with Compression Streams API and Node.js zlib

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

isomorphic-compress

GitHub Actions License NPM version NPM package size

Uses the native zlib API in Node.js and the Compression Streams API everywhere else. Tiny bundle with native performance.

Installation

npm install isomorphic-compress # npm
yarn add isomorphic-compress    # yarn
pnpm add isomorphic-compress    # pnpm

Usage

Documentation is also available at this URL: https://npmx.dev/package-docs/isomorphic-compress.

// Import `compress` and `decompress` to select formats "gzip", "deflate" (zlib), or "deflate-raw"
import { compress, decompress } from "isomorphic-compress";

// "H4sIAAAAAAAAE/NIzcnJVyjPL8pJUQQAlRmFGwwAAAA="
(await compress(new TextEncoder().encode("Hello world!"), "gzip")).toBase64();
// "Hello world!"
new TextDecoder().decode(
  await decompress(
    Uint8Array.fromBase64("H4sIAAAAAAAAE/NIzcnJVyjPL8pJUQQAlRmFGwwAAAA="),
    "gzip",
  ),
);

// You can also import each format's respective function (deflate/inflate, gzip/gunzip, zlib/unzlib)
import { zlib, unzlib } from "isomorphic-compress";

(await zlib(new Uint8Array())).toBase64(); // "eJwDAAAAAAE="
(await unzlib(Uint8Array.fromBase64("eJwDAAAAAAE="))).toBase64(); // ""

// Each format (deflate, gzip, zlib)'s entrypoint is also exported
import { deflate, inflate } from "isomorphic-compress/deflate.js";

(await deflate(new Uint8Array())).toBase64(); // "AwA="
(await inflate(Uint8Array.fromBase64("AwA="))).toBase64(); // ""

Compatibility

The Compression Streams API is baseline available across all browsers since May 2023 for compression formats deflate, gzip, and deflate-raw.1

Compression format Chrome Edge Firefox Safari
deflate 80 80 113 16.4
deflate-raw 103 103 113 16.4
gzip 80 80 113 16.4

Node.js added support for deflate, gzip, and deflateRaw in Node v0.6.02 and util.promisify in v8.0.0.3 Node.js has supported conditional exports since version 12.16.0.4 This package is supported for Bun v0.5.2 and Deno v2.4.

Notes

Why should I use this over fflate, pako?

In Node.js, isomorphic-compress uses the native zlib API; in other runtimes, including browsers, it uses the Compression Streams API. This means the library has a tiny code footprint compared to JavaScript-based implementations. Furthermore, a native implementation is faster; according to Facebook benchmarks, native compression libraries outperformed their JavaScript counterparts by 20x and their WebAssembly counterparts by 10x.5

However, there are some caveats. Since the browser implementation is backed by the Compression Streams API, the compression and decompression functions are all asynchronous. This also means that performance will suffer for small inputs due to the overhead of promises.

Why shouldn't I just use the Compression Streams API?

You probably should if you fully intend to write runtime-agnostic code, as Node.js has supported the feature since Node 18.1 However, there is a large performance hit that occurs when using the Node.js Compression Streams API. Vercel found that Node.js web streams could be improved by 10x by recreating their interfaces with Node streams.6 Furthermore, there is also reduced performance when the data is already loaded into memory and is not streamed.

By instead using the native zlib API in Node, compression and decompression have significantly higher throughput. This package does this with conditional exports.

Why are the functions named like that?

I used the function naming scheme of fflate for the individual functions:

pako fflate Node.js zlib
deflate / inflate zlib / unzlib deflate / inflate
deflateRaw / inflateRaw deflate / inflate deflateRaw / inflateRaw
gzip / ungzip gzip / gunzip gzip / gunzip

License

This project is licensed under the MIT License. See the LICENSE file for details.

Footnotes

Footnotes

  1. https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API#browser_compatibility ↩ ↩2

  2. https://nodejs.org/api/zlib.html#zlibdeflatebuffer-options-callback ↩

  3. https://nodejs.org/api/util.html#utilpromisifyoriginal ↩

  4. https://nodejs.org/api/packages.html#conditional-exports ↩

  5. https://github.com/whatwg/compression/blob/main/explainer.md#motivation ↩

  6. https://vercel.com/blog/we-ralph-wiggumed-webstreams-to-make-them-10x-faster ↩

About

Isomorphic, native (de)compression with Compression Streams API and Node.js zlib

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages