npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

xz-compat

v1.2.1

Published

XZ Decompression Library

Readme

xz-compat

XZ Decompression Library

xz-compat is a complete pure JavaScript implementation of XZ decompression with support for LZMA2 compression, BCJ filters (Branch Conversion for various CPU architectures), and Delta filtering. Compatible with Node.js 0.8+.

Features

  • XZ Format Support: Full XZ container format decoding
  • LZMA2 Decoder: Complete LZMA2 decompression implementation
  • High-Level 7z API: Streamlined decoding for 7z files with automatic native acceleration
  • BCJ Filters: Branch conversion for improved compression on executables
    • x86 (32-bit)
    • ARM (32-bit)
    • ARM64 / AArch64
    • ARM Thumb
    • PowerPC
    • SPARC
    • IA64 / Itanium
  • Delta Filter: Byte-level delta encoding
  • Streaming & Sync: Both streaming transforms and synchronous decoding
  • Node 0.8+: Works on legacy Node.js versions
  • Native Acceleration: Optional lzma-native on Node.js 10+ for 3-5x performance boost

Installation

npm install xz-compat

Optional Native Acceleration

For Node.js 10+, install lzma-native for automatic performance boost:

npm install lzma-native

This provides 3-5x faster decompression. The library automatically detects and uses native bindings when available, falling back to pure JavaScript on older Node versions, when installation fails, or when disabled via LZMA_NATIVE_DISABLE=1.

Quick Start

XZ Decompression (Self-describing format)

import { readFileSync } from 'fs';
import { decodeXZ } from 'xz-compat';

const compressedData = readFileSync('file.xz');
const decompressedData = decodeXZ(compressedData);
console.log('Decompressed:', decompressedData.toString());

Streaming XZ Decompression

import { createReadStream } from 'fs';
import { createXZDecoder } from 'xz-compat';

const input = createReadStream('file.xz');
const decoder = createXZDecoder();

input.pipe(decoder);
decoder.on('data', (chunk) => {
  console.log('Decompressed chunk:', chunk);
});

7z LZMA/LZMA2 Decompression (High-level API)

import { decode7zLzma2, decode7zLzma } from 'xz-compat';

// Decompress LZMA2 from a 7z file (properties extracted separately)
const lzma2Data = readFileSync('data.7z');
const lzma2Properties = /* from 7z folder structure */;
const decompressed = decode7zLzma2(lzma2Data, lzma2Properties);

LZMA/LZMA2 (Low-level API)

import { decodeLzma2 } from 'xz-compat';
import { writeFileSync } from 'fs';

const lzma2Data = readFileSync('data.lzma2');
const chunks = [];

decodeLzma2(lzma2Data, lzma2Properties, expectedSize, {
  write: (chunk) => {
    chunks.push(chunk);
  }
});

const decompressed = Buffer.concat(chunks);
writeFileSync('output.bin', decompressed);

Using BCJ Filters Directly

import { decodeBcj, decodeBcjArm } from 'xz-compat';

// Decode x86 BCJ filtered data
const x86Data = readFileSync('filtered-x86.bin');
const unfiltered = decodeBcj(x86Data);

// Decode ARM BCJ filtered data
const armData = readFileSync('filtered-arm.bin');
const unfilteredArm = decodeBcjArm(armData);

API Reference

High-Level APIs (Recommended)

XZ Decompression

decodeXZ(buffer: Buffer): Buffer

Synchronously decompresses XZ format data.

  • Automatic native acceleration: Uses lzma-native when available on Node 10+
  • Self-describing: Properties embedded in XZ format

createXZDecoder(): Transform

Creates a streaming Transform for XZ decompression.

  • Automatically uses native acceleration when available

7z LZMA/LZMA2 Decompression

decode7zLzma2(data: Buffer, properties: Buffer, unpackSize?: number): Buffer

Decompresses LZMA2 data from a 7z file.

  • Accepts properties separately (matching 7z format)
  • Tries native acceleration via lzma-native automatically
  • Falls back to pure JavaScript if native unavailable

decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number): Buffer

Decompresses LZMA1 data from a 7z file.

  • Accepts 5-byte properties separately
  • Tries native acceleration automatically

Low-Level APIs (Specialized Use)

LZMA Decompression

decodeLzma(buffer: Buffer, properties: Buffer, outSize: number, sink?: OutputSink): Buffer

Synchronously decodes LZMA1 compressed data.

  • Low-level API for raw LZMA data
  • Requires separate properties and output size

createLzmaDecoder(properties: Buffer, outSize: number): Transform

Creates a streaming Transform for LZMA1 decompression.

LZMA2 Decompression

decodeLzma2(buffer: Buffer, properties: Buffer, unpackSize: number, sink?: OutputSink): Buffer

Synchronously decodes LZMA2 compressed data.

createLzma2Decoder(properties: Buffer, unpackSize?: number): Transform

Creates a streaming Transform for LZMA2 decompression.

BCJ Filters

Branch Conversion (BCJ) filters improve compression of executables by converting relative branch addresses to absolute addresses, creating more repetitive patterns.

All BCJ filters follow the same interface:

  • decodeBcj*(buffer: Buffer, properties?: Buffer, unpackSize?: number): Buffer
  • createBcj*Decoder(properties?: Buffer, unpackSize?: number): Transform

Supported BCJ filters:

  • decodeBcj / createBcjDecoder - x86 (32-bit)
  • decodeBcjArm / createBcjArmDecoder - ARM (32-bit)
  • decodeBcjArm64 / createBcjArm64Decoder - ARM64 / AArch64
  • decodeBcjArmt / createBcjArmtDecoder - ARM Thumb
  • decodeBcjPpc / createBcjPpcDecoder - PowerPC
  • decodeBcjSparc / createBcjSparcDecoder - SPARC
  • decodeBcjIa64 / createBcjIa64Decoder - IA64 / Itanium

Delta Filter

decodeDelta(buffer: Buffer, distance?: Buffer): Buffer

Decodes Delta filtered data (inter-byte differences).

Use Cases

1. Decompressing XZ Archives

import { createReadStream } from 'fs';
import { createXZDecoder } from 'xz-compat';
import { pipeline } from 'stream/promises';

async function decompressXZ(inputPath, outputPath) {
  await pipeline(
    createReadStream(inputPath),
    createXZDecoder(),
    createWriteStream(outputPath)
  );
}

2. Working with LZMA Compressed Files

import { decodeLzma2 } from 'xz-compat';

// Decompress raw LZMA2 stream
const data = readFileSync('data.lzma2');
const chunks = [];

decodeLzma2(data, propertiesBuffer, uncompressedSize, {
  write: (chunk) => chunks.push(chunk)
});

const result = Buffer.concat(chunks);

3. Batch Processing Compressed Files

import { decodeXZ } from 'xz-compat';

function processXZFiles(filePaths) {
  return filePaths.map(file => {
    const compressed = readFileSync(file);
    const decompressed = decodeXZ(compressed);
    // Process decompressed data
    return processData(decompressed);
  });
}

Technical Details

XZ Format Structure

XZ is a container format that wraps LZMA2 compressed data:

  1. Stream Header
  2. One or more Blocks (each with Block Header + Compressed Data)
  3. Index (records block positions)
  4. Stream Footer

Each Block can contain:

  • A chain of preprocessing filters (Delta, BCJ)
  • LZMA2 compression

BCJ Filter Algorithm

BCJ filters convert branch instructions in executable code:

x86 Example:

  • Original: E8 xx xx xx xx (CALL with relative offset)
  • Converted: E8 aa aa aa aa (CALL with absolute address)

This creates more repetitive patterns for better LZMA2 compression.

Reference Implementation

This implementation is based on the reference XZ Utils (XZ Embedded) codebase:

  • XZ Utils GitHub
  • Filter algorithms match the xz embedded reference implementations

Compatibility

  • Node.js: 0.8 and above
  • Browser: Not tested (designed for Node.js)
  • Dependencies: None (pure JavaScript)

Differences from Native XZ

This is a decompression-only implementation focused on compatibility and ease of use:

  • No compression support (only decompression)
  • Simplified streaming interface
  • Pure JavaScript (no native bindings)
  • Optimized for readability and maintainability

Performance

Performance characteristics:

  • Synchronous: Suitable for small to medium files
  • Streaming: Memory-efficient for large files
  • Trade-off: Pure JavaScript may be slower than native implementations
  • BCJ Decoding: Optimized reference algorithm implementations

License

MIT

Contributing

Contributions welcome! Please ensure tests pass:

npm test

References