Minizlib Compression Streams
minizlib is a high-performance JavaScript library designed for stream-based compression and decompression using zlib, gzip, Brotli, and Zstd algorithms. It leverages Node.js's native zlib bindings for optimal speed, providing a synchronous streaming API built on top of the 'minipass' stream implementation. The current stable version is 3.1.0, actively maintained with a focus on efficiency. A key differentiator is its synchronous operation on the main thread, which minimizes overhead and offers immediate processing, making it suitable for CPU-bound tasks in scenarios where consistent asynchronous behavior of Node's core `stream.Transform` might introduce undesirable latency. Unlike Node.js's built-in `zlib` module, minizlib exclusively provides stream interfaces and does not offer convenience methods for buffer-to-buffer compression/decompression, requiring users to compose streams for such tasks. It was developed to meet the demanding requirements of projects like 'node-tar' and 'minipass-fetch'.
Common errors
-
TypeError: (0 , minizlib__WEBPACK_IMPORTED_MODULE_0__.BrotliDecompress) is not a function
cause Attempting to use `BrotliDecompress` as a default export in an environment that expects named exports (e.g., in a bundler context or with incorrect CommonJS interop).fixEnsure you are using named imports: `import { BrotliDecompress } from 'minizlib';` or `const { BrotliDecompress } = require('minizlib');`. -
Error: The 'chunk' argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Object
cause Attempting to `write()` or `end()` a stream with data that is not a Buffer, Uint8Array, or string, which is a common mistake when piping complex objects.fixEnsure that the data being piped into or written to `minizlib` streams (or any Minipass stream) is always a Buffer, Uint8Array, or string type. Transform non-compliant data upstream if necessary. -
ReferenceError: Deflate is not defined
cause Attempting to use a minizlib class (e.g., `Deflate`, `Gzip`) without correctly importing or requiring it.fixAdd the appropriate import or require statement: `import { Deflate } from 'minizlib';` or `const { Deflate } = require('minizlib');`.
Warnings
- gotcha minizlib performs compression and decompression synchronously on the main event loop thread. While fast, processing extremely large amounts of data or many concurrent operations can block the event loop, potentially affecting application responsiveness.
- gotcha Unlike Node.js's core `zlib` module, minizlib does not provide convenience methods (e.g., `zlib.deflateSync`, `zlib.gzip`) for compressing/decompressing entire buffers. It is exclusively a stream-based API.
- gotcha Brotli compression/decompression support is only available in Node.js environments that include the native Brotli binding (Node.js v10+). Zstd support requires Node.js v22.15 or higher.
- gotcha For reproducible gzip compressed files across different operating systems, the 'portable' option must be explicitly set to `true` when initializing a `Gzip` stream. This standardizes the OS indicator byte in the gzip header to `0xFF` ('unknown').
Install
-
npm install minizlib -
yarn add minizlib -
pnpm add minizlib
Imports
- Deflate
const Deflate = require('minizlib').Deflateimport { Deflate } from 'minizlib' - BrotliDecompress
const BrotliDecompress = require('minizlib').defaultimport { BrotliDecompress } from 'minizlib' - Gzip
import Gzip from 'minizlib'
import { Gzip } from 'minizlib'
Quickstart
import { BrotliDecompress } from 'minizlib';
import { Readable, Writable } from 'stream'; // Node.js built-in streams for simulation
// Simulate a source of compressed data using a custom Readable stream
class CompressedDataSource extends Readable {
private chunks: Buffer[];
constructor(data: Buffer) {
super();
this.chunks = [data]; // In a real app, 'data' would be actual compressed content
}
_read() {
if (this.chunks.length > 0) {
this.push(this.chunks.shift());
} else {
this.push(null); // Signal end of stream
}
}
}
// Simulate a destination for decoded data using a custom Writable stream
class DecodedDataDestination extends Writable {
private receivedData: Buffer[] = [];
constructor() {
super();
}
_write(chunk: Buffer, encoding: string, callback: (error?: Error | null) => void) {
this.receivedData.push(chunk);
callback();
}
getData(): Buffer {
return Buffer.concat(this.receivedData);
}
}
async function runDecompression() {
// For demonstration, we use a simple Brotli-compressed hex string.
// In a real application, this would come from a file, network, etc.
// Note: minizlib doesn't provide direct buffer compression, so this input is pre-compressed.
const compressedBrotliHex = 'C323040B001402000000A1302A0B50616464656420546869732069732073616D706C65206461746120746F20626520636F6D7072657373656420616E64207468656E206465636F6D70726573736564207573696E67206D696E697A6C69622E';
const mockCompressedBuffer = Buffer.from(compressedBrotliHex, 'hex');
const inputSource = new CompressedDataSource(mockCompressedBuffer);
const decompressStream = new BrotliDecompress();
const outputDestination = new DecodedDataDestination();
await new Promise<void>((resolve, reject) => {
inputSource.pipe(decompressStream).pipe(outputDestination)
.on('finish', () => {
console.log('Decompression finished successfully.');
console.log('Decoded data:', outputDestination.getData().toString('utf8'));
resolve();
})
.on('error', (err) => {
console.error('Decompression error:', err);
reject(err);
});
});
}
runDecompression().catch(console.error);