JavaScript Compression Streams API Gzip Guide
The Compression Streams API is a native web API that enables
JavaScript to compress and decompress data streams directly in the
browser or supported runtime environments without external libraries.
This article explores how the Compression Streams API works and provides
practical code examples demonstrating how to compress and decompress raw
data using standard gzip compression.
What is the Compression Streams API?
The Compression Streams API provides built-in browser primitives for data compression using standard stream interfaces. Traditionally, client-side data compression required third-party JavaScript libraries such as Pako. With the Compression Streams API, compression is handled natively by the browser engine, resulting in smaller bundle sizes and improved execution performance.
The API exposes two core interfaces:
CompressionStream: ATransformStreamthat compresses raw data into formats such asgzip,deflate, ordeflate-raw.DecompressionStream: ATransformStreamthat decompresses encoded binary streams back to their original state.
Compressing Raw Data with Gzip
To compress data, the raw input—typically a string or binary
buffer—is converted into a ReadableStream, piped through an
instance of CompressionStream('gzip'), and consumed as
compressed binary output.
Here is a step-by-step example compressing a plain text string into a
gzip-compressed Uint8Array:
async function compressData(inputString) {
// 1. Convert the string into a Uint8Array
const textEncoder = new TextEncoder();
const rawBytes = textEncoder.encode(inputString);
// 2. Create a stream from the raw bytes
const byteStream = new ReadableStream({
start(controller) {
controller.enqueue(rawBytes);
controller.close();
}
});
// 3. Initialize the gzip compression stream
const compressionStream = new CompressionStream('gzip');
// 4. Pipe the byte stream through the compression stream
const compressedStream = byteStream.pipeThrough(compressionStream);
// 5. Convert the stream output to an ArrayBuffer using the Response API
const compressedBuffer = await new Response(compressedStream).arrayBuffer();
return new Uint8Array(compressedBuffer);
}Explanation of the Steps
- Text Encoding: The
TextEncodertranslates the human-readable string into a stream-compatibleUint8Array. - Stream Creation: A
ReadableStreamis initialized to feed the encoded binary data into the pipeline. - CompressionStream Initialization: Calling
new CompressionStream('gzip')specifies the target format. - Piping: The
pipeThrough()method forwards raw chunks into the compressor, which continuously yields compressed chunks. - Response Consumption: Wrapping the resulting stream
inside a
Responseobject allows the use of.arrayBuffer(), which reads the entire stream until completion and returns the final compressed buffer.
Decompressing Gzip Data
Decompressing data follows the inverse process using
DecompressionStream:
async function decompressData(compressedBytes) {
// 1. Create a readable stream from the compressed byte array
const byteStream = new ReadableStream({
start(controller) {
controller.enqueue(compressedBytes);
controller.close();
}
});
// 2. Initialize the gzip decompression stream
const decompressionStream = new DecompressionStream('gzip');
// 3. Pipe compressed data through the decompressor
const decompressedStream = byteStream.pipeThrough(decompressionStream);
// 4. Read the stream as an ArrayBuffer and decode to string
const decompressedBuffer = await new Response(decompressedStream).arrayBuffer();
const textDecoder = new TextDecoder();
return textDecoder.decode(decompressedBuffer);
}Key Use Cases
- Reducing Network Payloads: Compress large JSON structures, logs, or analytics events before uploading them to a server.
- IndexedDB Optimization: Store compressed binary data inside client-side databases to reduce storage footprint.
- File Uploads and Downloads: Compress generated client-side assets (such as CSV exports) before triggering a user download.