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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@blaizejs/middleware-compression

v1.0.0

Published

Production-ready compression middleware for BlaizeJS

Readme

@blaizejs/middleware-compression

Production-ready HTTP compression middleware for BlaizeJS. Supports gzip, deflate, Brotli, and Zstandard with automatic content negotiation, configurable presets, and graceful runtime fallback.

Installation

# pnpm (recommended)
pnpm add @blaizejs/middleware-compression

# npm
npm install @blaizejs/middleware-compression

Peer dependency: blaizejs must be installed in your project (^0.9.2).

Quick Start

import { createServer } from 'blaizejs';
import { createCompressionMiddleware } from '@blaizejs/middleware-compression';

const server = createServer();

// Zero-config — uses sensible defaults
server.use(createCompressionMiddleware());

server.get('/hello', ({ ctx }) => {
  ctx.response.json({ message: 'Hello, compressed world!' });
});

Alias: compression is available as a shorter alias for createCompressionMiddleware.

Configuration Reference

Pass a CompressionOptions object to customise behaviour:

server.use(createCompressionMiddleware({
  algorithms: ['br', 'gzip'],
  level: 'best',
  threshold: 512,
}));

| Option | Type | Default | Description | |---|---|---|---| | algorithms | CompressionAlgorithm[] | ['zstd','br','gzip','deflate'] | Preferred algorithm order for negotiation. | | level | 'fastest' \| 'default' \| 'best' \| number | 'default' | Compression level — named preset or numeric value clamped to the algorithm's valid range. | | threshold | number | 1024 | Minimum response size in bytes before compression is applied. | | contentTypeFilter | boolean \| function \| { include?, exclude? } | Built-in list | Filter which MIME types are compressed. Supports wildcard patterns (e.g., text/*) in include/exclude arrays. | | skip | (ctx: Context) => boolean \| Promise<boolean> | — | Return true to skip compression for a request. | | vary | boolean | true | Whether to set the Vary: Accept-Encoding response header. | | flush | boolean | false | Flush compression buffers after each write. Useful for streaming. | | memoryLevel | number (1–9) | 8 | Memory allocation level. Only affects gzip and deflate. | | windowBits | number | — | Window size for zlib-based algorithms (gzip/deflate). | | brotliQuality | number (0–11) | — | Brotli-specific quality override. | | preset | CompressionPreset | — | Use a named preset (see below). |

Presets

Five built-in presets cover common use cases. Use them directly or via convenience factories:

import {
  createCompressionMiddleware,
  compressionFast,
  compressionBest,
  compressionTextOnly,
  compressionStreaming,
  getCompressionPreset,
} from '@blaizejs/middleware-compression';

// Via preset option
server.use(createCompressionMiddleware({ preset: 'fast' }));

// Via convenience factory
server.use(compressionFast());

// Via getCompressionPreset helper
server.use(createCompressionMiddleware(getCompressionPreset('best')));

| Preset | threshold | level | flush | contentTypeFilter | Use Case | |---|---|---|---|---|---| | default | 1024 | 'default' | false | — | Balanced default for most apps. | | fast | 1024 | 'fastest' | false | — | Low-latency APIs where CPU is constrained. | | best | 512 | 'best' | false | — | Maximum compression ratio (static assets, infrequent responses). | | text-only | 1024 | 'default' | false | { include: ['text/*'] } | Only compress text content types; skip binary payloads. | | streaming | 0 | 'default' | true | — | Streaming responses where Content-Length is unknown. |

Per-Route Configuration

Apply different compression settings to individual routes by using separate middleware instances:

import { createCompressionMiddleware, compressionFast } from '@blaizejs/middleware-compression';

// Global default
server.use(createCompressionMiddleware());

// Fast compression for a latency-sensitive API group
server.group('/api/realtime', (group) => {
  group.use(compressionFast());
  group.get('/feed', handler);
});

// Best compression for a static-like endpoint
server.group('/reports', (group) => {
  group.use(createCompressionMiddleware({ level: 'best', threshold: 256 }));
  group.get('/:id', handler);
});

Flush Modes

The flush option controls how aggressively compression buffers are flushed. This matters most for streaming responses.

| Value | Behaviour | Trade-off | |---|---|---| | false | No explicit flushing (default). | Best compression ratio; data may be buffered. | | true | Z_SYNC_FLUSH after each write. | Lower latency for streamed chunks; slightly worse ratio. |

Logging

Compression events are logged through BlaizeJS's built-in logger at the debug level. Set your server's log level to debug to see compression diagnostics:

Compression skipped  { reason: 'below-threshold' }
Compressed response  { algorithm: 'br', originalSize: 14280, compressedSize: 3912, ratio: 0.274 }

Error-level logs are emitted when compression fails (the response is sent uncompressed as a fallback):

Compression failed, sending uncompressed  { error: '...', algorithm: 'gzip' }

Algorithm Notes

| Algorithm | Encoding | Node.js Requirement | Notes | |---|---|---|---| | Zstandard | zstd | 22.15.0+ / 24.0.0+ | Best ratio + speed. Falls back gracefully if zlib.createZstdCompress is unavailable. | | Brotli | br | 10.16.0+ | Excellent ratio for text. Available on all modern Node.js versions. | | gzip | gzip | All | Universally supported. Good baseline. | | deflate | deflate | All | Similar to gzip, slightly less overhead. |

Fallback Chain

When the middleware is created, detectAvailableAlgorithms checks which algorithms are available in the current Node.js runtime. Unavailable algorithms (e.g., zstd on Node.js < 22.15) are excluded from negotiation. At request time, the client's Accept-Encoding header is matched against the remaining available algorithms in priority order. If no match is found, the response is sent uncompressed. If compression fails at runtime, the response falls back to uncompressed delivery and the error is logged.

Middleware Placement

Compression middleware should be registered early in the middleware chain — before any middleware that sends responses.

const server = createServer();

// ✅ Register compression FIRST
server.use(createCompressionMiddleware());

// Then other middleware
server.use(cors());
server.use(logger());

// Route handlers
server.get('/data', handler);

The middleware works by wrapping ctx.response.json, ctx.response.text, ctx.response.html, and ctx.response.stream before next() is called. If registered too late (after a middleware that already sends the response), responses go out uncompressed — this is a silent failure. This follows the same pattern as Express's compression() middleware.

HTTP/2

No special handling is needed. The compression middleware works transparently with HTTP/2 connections — content negotiation via Accept-Encoding operates identically regardless of protocol version.

API Reference

Exports

| Export | Type | Description | |---|---|---| | createCompressionMiddleware(options?) | (options?: CompressionOptions) => Middleware | Main factory — creates a compression middleware instance. | | compression(options?) | Alias | Shorter alias for createCompressionMiddleware. | | compressionFast() | () => Middleware | Convenience factory using the fast preset. | | compressionBest() | () => Middleware | Convenience factory using the best preset. | | compressionTextOnly() | () => Middleware | Convenience factory using the text-only preset. | | compressionStreaming() | () => Middleware | Convenience factory using the streaming preset. | | getCompressionPreset(name) | (name: CompressionPreset) => CompressionOptions | Returns the options object for a named preset. | | compressionPresets | Record<CompressionPreset, CompressionOptions> | Direct access to all preset option objects. |

License

MIT