inflate deflate using zlib library via nitro module
npm install @strawberrytech/react-native-nitro-zlibHigh-performance deflate and inflate compression/decompression for React Native with support for multiple formats (GZIP, Zlib, Raw deflate) using the native zlib library via Nitro Modules.
- React Native New Architecture enabled (Nitro Modules / JSI)
- react-native-nitro-modules installed
``sh`
npm install @strawberrytech/react-native-nitro-zlib react-native-nitro-modules
`sh`
yarn add @strawberrytech/react-native-nitro-zlib react-native-nitro-modules
On iOS, install pods:
`sh`
npx pod-install
`ts
import { deflate, inflate, Format } from '@strawberrytech/react-native-nitro-zlib';
// Setup encoder (e.g., using react-native-fast-encoder)
const encoder = new TextEncoder();
const decoder = new TextDecoder();
// Compress with GZIP (default)
const input = encoder.encode('Hello World').buffer;
const compressed = deflate(input);
const decompressed = inflate(compressed);
const result = decoder.decode(decompressed); // 'Hello World'
`
The library supports multiple compression formats:
`ts
import { deflate, inflate, Format } from '@strawberrytech/react-native-nitro-zlib';
// GZIP format (default) - most common, used for .gz files and HTTP compression
const gzipped = deflate(input, Format.GZIP);
const ungzipped = inflate(gzipped); // AUTO-detects format
// Zlib format - used in PNG, PDF, and some network protocols
const zlibbed = deflate(input, Format.ZLIB);
const unzlibbed = inflate(zlibbed); // AUTO-detects format
// Raw deflate - no headers, used inside ZIP, PNG, and other containers
// ⚠️ IMPORTANT: RAW format requires explicit matching - AUTO cannot detect it!
const rawCompressed = deflate(input, Format.RAW);
const rawDecompressed = inflate(rawCompressed, Format.RAW); // Must use Format.RAW!
// Auto-detect format on inflate (default) - works with GZIP and Zlib only
const autoDetected = inflate(compressed); // Automatically detects GZIP or Zlib
`
> Warning: Format.AUTO cannot detect raw deflate because it has no headers. When using Format.RAW for compression, you must use Format.RAW for decompression as well.
Control the compression ratio vs. speed tradeoff with the level parameter (1-9):
`ts
// Level 1: Fastest compression, larger output
const fast = deflate(input, Format.GZIP, 1);
// Level 6: Balanced (good for most use cases)
const balanced = deflate(input, Format.GZIP, 6);
// Level 9: Best compression, slower (default)
const best = deflate(input, Format.GZIP, 9);
`
The async versions run on a background thread pool, keeping the JS thread responsive:
`ts
import { deflateAsync, inflateAsync, Format } from '@strawberrytech/react-native-nitro-zlib';
const input = encoder.encode('Large data...').buffer;
// Compress asynchronously with GZIP
const compressed = await deflateAsync(input, Format.GZIP, 9);
// Decompress asynchronously (AUTO-detects GZIP/Zlib)
const decompressed = await inflateAsync(compressed);
// For RAW format, must use matching format for both
const rawCompressed = await deflateAsync(input, Format.RAW, 9);
const rawDecompressed = await inflateAsync(rawCompressed, Format.RAW);
`
`ts`
type ZlibFormat = "raw" | "zlib" | "gzip" | "auto";
The Format object provides convenient constants, but you can also use string literals directly:
`ts
// Using Format constants (recommended)
Format.GZIP // "gzip" - GZIP wrapper (default for deflate)
Format.ZLIB // "zlib" - Zlib wrapper
Format.RAW // "raw" - Raw deflate (no headers)
Format.AUTO // "auto" - Auto-detect format (inflate only, default)
// Or use string literals directly
deflate(data, "gzip");
inflate(data, "raw");
`
`ts
// Synchronous compression
function deflate(
data: ArrayBuffer,
format?: ZlibFormat, // Default: Format.GZIP
level?: number // Default: 9 (best compression)
): ArrayBuffer;
// Synchronous decompression
function inflate(
data: ArrayBuffer,
format?: ZlibFormat // Default: Format.AUTO (auto-detects zlib/gzip)
): ArrayBuffer;
// Asynchronous compression (background thread)
function deflateAsync(
data: ArrayBuffer,
format?: ZlibFormat, // Default: Format.GZIP
level?: number // Default: 9 (best compression)
): Promise
// Asynchronous decompression (background thread)
function inflateAsync(
data: ArrayBuffer,
format?: ZlibFormat // Default: Format.AUTO (auto-detects zlib/gzip)
): Promise
`
- 1: Fastest compression, largest output size
- 2-5: Progressive tradeoff between speed and size
- 6: Balanced (good default for most cases)
- 7-8: Better compression, slower
- 9: Best compression, slowest (library default)
| Format | Window Bits | Use Cases | Headers/Trailers |
|--------|-------------|-----------|------------------|
| Format.GZIP | 31 | .gz files, HTTP compression | 10+ byte header, 8-byte trailer (CRC-32 + size) |Format.ZLIB
| | 15 | PNG, PDF, network protocols | 2-byte header, 4-byte trailer (Adler-32) |Format.RAW
| | -15 | ZIP files, PNG chunks, custom containers | None |Format.AUTO
| | 47 | Auto-detection (inflate only) | Automatically detects GZIP or Zlib |
- Use async methods for data > 100KB to avoid blocking the JS thread
- Choose the right format:
- GZIP: Best for standalone files, HTTP responses
- Zlib: Good for embedding in other formats
- Raw: Smallest overhead when you manage headers yourself
- Adjust compression level based on your needs:
- Level 1-3: Fast, good for real-time compression
- Level 6: Balanced, recommended for most cases
- Level 9: Best ratio, use when size matters more than speed
- Thread Safety: When calling async methods, the ArrayBuffer is copied if it is not already an owning buffer to ensure it remains valid on the background thread.Format.AUTO
- Auto-detect: only works with inflate() and automatically detects GZIP or Zlib format. It cannot be used with deflate().gzip
- Compatibility: GZIP output is compatible with command-line and standard HTTP Content-Encoding: gzip.example/src/App.tsx
- For a complete working example with UI, see .
- Development workflow: CONTRIBUTING.mdCODE_OF_CONDUCT.md`
- Code of conduct:
MIT
---
Made with create-react-native-library