brotli-wasm
Part of HTTP Toolkit: powerful tools for building, testing & debugging HTTP(S)
A reliable compressor and decompressor for Brotli, supporting node & browsers via wasm
Brotli is available in modern Node (12+) but not older Node or browsers. With this package, you can immediately use it everywhere.
This package contains a tiny wrapper around the compress & decompress API of the Rust Brotli crate, compiled to wasm with just enough setup to make it easily usable from JavaScript.
This is battle-tested, in production use in both node & browsers as part of HTTP Toolkit, and includes automated build with node & browser tests to make sure.
Getting started
npm install brotli-wasm
You should be able to import this directly into Node, as normal, or in a browser using any bundler that supports ES modules & webassembly (e.g. Webpack v4 or v5, Vite, Rollup, and most others).
For each target (node.js, commonjs bundlers & ESM bundlers) this module exports a different WASM file & setup, with a slightly different entrypoint. These entrypoints all expose a consistent default-export API, in addition to some other exports that may vary (e.g. Node exposes the brotli methods synchronously, while browsers always require an await
due to WASM limitations).
In all builds (after waiting for the exported promise in browsers) the module exposes two core methods:
compress(Buffer, [options])
- compresses a buffer using Brotli, returning the compressed buffer. An optional options object can be provided. The only currently supported option is quality
: a number between 1 and 11.decompress(Buffer)
- decompresses a buffer using Brotli, returning the original raw data.
For advanced use data-streaming use cases, CompressStream
and DecompressStream
classes for streaming compression are also available. See the tests for example usage.
Usage
In node.js:
const * as brotli = require('brotli-wasm');
const compressedData = brotli.compress(Buffer.from('some input'));
const decompressedData = brotli.decompress(compressedData);
console.log(Buffer.from(decompressedData).toString('utf8'));
In browsers:
import brotliPromise from 'brotli-wasm';
const brotli = await brotliPromise;
const compressedData = brotli.compress(Buffer.from('some input'));
const decompressedData = brotli.decompress(compressedData);
console.log(Buffer.from(decompressedData).toString('utf8'));
The package itself has no runtime dependencies, but you will need a browser Buffer polyfill for the above example code, or you can do the same using TextEncoder/Decoder instead if you prefer.
If you want to support node & browsers with the same code, you can use the await
form with the default export everywhere.
Alternatives
There's a few other packages that do similar things, but I found they were all unusable and/or unmaintained:
- brotli-dec-wasm - decompressor only, compiled from Rust just like this package, actively maintained, but no compressor available (by design). If you only need decompression, this package is a good choice.
- Brotli.js - hand-written JS decompressor that seems to work OK for most cases, but it crashes for some edge cases and the emscripten build of the compressor doesn't work in browsers at all. Last updated in 2017.
- wasm-brotli - Compiled from Rust like this package, includes decompressor & compressor, but requires a custom async wrapper for Webpack v4 usage and isn't usable at all in Webpack v5. Last updated in 2019.