zlib for WebAssembly
v1.3.2WebAssemblyzlib 1.3.2 for browsers, Node.js and edge runtimes, precompiled for wasm32, single-threaded and multi-threaded as @crossbind/port-zlib-wasm.
Install
crossbind itself arrives with your bundler plugin, or with a new project from npm create crossbind@beta; Bundlers has Vite, Webpack, Rspack and Rollup.
Usage
Each example runs here, in this tab, and prints what the site build checked.
Each example also has a JavaScript only tab: the same task with no C++ file, calling zlib's own headers from @crossbind/port-zlib directly. 4 of 5 work that way; the other says what stops it.
Compress and decompress a buffer
The two calls most zlib code makes: compress2 at a chosen level, and uncompress with the original size the caller kept.
The same compress2 and uncompress calls as the C++. JavaScript now allocates the buffers, copies bytes in and out as one character per byte, and passes each length as a uLongf *: a 4-byte handle that zlib reads as the room it has and overwrites with the size it used. Z_OK and zlib's other constants are macros, which do not cross, so the check compares with 0.
Write a .gz that remembers its file name
deflateInit2 with windowBits 15 + 16 writes gzip instead of zlib, and deflateSetHeader fills the header fields that gunzip -N restores. inflateGetHeader reads them back.
zlib's gz file calls write and read the .gz in /memfs, but gzopen writes a header with no name and a time of 0, and deflateSetHeader and inflateGetHeader, which fill and read those fields, need gz_header and z_stream fields that crossbind does not bind. So JavaScript writes the name and the time into the header and reads them back from the bytes; the file is byte for byte the one the C++ writes.
Stream a file through gzip
For data you should not hold in one buffer: the deflate() and inflate() loops of zpipe.c, the example that ships with zlib, work file to file in 64 KB steps.
The deflate() and inflate() loops cannot run from JavaScript: they read and advance the next_in, avail_in, next_out and avail_out fields of z_stream, which crossbind does not bind, so deflate returns -2 (Z_STREAM_ERROR). zlib's gz file calls stream instead, in the same 64 KiB steps and with the same sizes.
Compress small messages with a preset dictionary
A short message has little to refer back to. Load earlier messages with deflateSetDictionary and inflateSetDictionary, and each new one compresses against them.
z_stream. deflateSetDictionary and inflateSetDictionary load it (both return 0 from JavaScript), but only deflate() and inflate() then compress or decompress, and they work through the next_in, avail_in, next_out and avail_out fields. crossbind binds z_stream as a class without fields, so what JavaScript assigns stays on the JavaScript object: deflate finds no output buffer and returns -2 (Z_STREAM_ERROR), and so does inflate. An allocBuffer block in place of the stream is refused ("Expected null or instance of z_stream"), and compress2 and the gz file calls take no dictionary. A preset dictionary takes the few lines of C++ in the other tab.Checksum data in pieces
crc32 and adler32 continue a running value across pieces, and crc32_combine and adler32_combine join the checksums of pieces computed separately.
The same four zlib functions. The C++ took strings; the C functions take a const Bytef * and a length, so each piece is copied into its own allocBuffer first. The length that crc32_combine and adler32_combine take is a 64-bit z_off_t, and a plain Number works for it.
What is different on WebAssembly
- In a browser the module runs in a Worker by default (
useWorker), so every call returns a promise:awaitcalls and constructors alike. - The module has its own filesystem:
m.FSwrites files,m.getFileBytesreads them back andm.autoMountFilesmountsFileobjects from an<input type=file>./memfslives in memory;/opfspersists across reloads and needs the Worker. See Filesystem. - In Node.js,
m.FSis the real disk, so use real paths there. - Multi-threaded builds (
runtime: 'mt') need COOP and COEP headers in production. See Threading.
Other platforms
- zlib overview: the apps, every platform's setup and the packages.
- zlib for Android: React Native apps on Android.
- zlib for iOS: React Native apps on iOS.
- zlib for WASI: command-line programs under wasmtime.
Facts on this page come from the port manifests in the repository and from what npm served on beta when the site was built. See the Libraries guide for the full consumer flow.