Koa Compress Middleware
`koa-compress` is a middleware for Koa.js applications that provides HTTP response compression. It is actively maintained, with the current stable version being 5.2.1, and demonstrates a consistent release cadence through regular patch and minor updates, such as `v5.2.0`, `v5.1.1`, and `v5.0.1`. The library automatically negotiates and applies various compression algorithms including `gzip`, `deflate`, `brotli` (br), and `zstandard` (zstd), adapting to client capabilities and server configuration. Key differentiators include its deep integration with the Koa context, allowing for granular control over compression via `ctx.compress` and `ctx.compress` as an options object. It offers flexible configuration for `filter` predicates, `threshold` for minimum compressible size, and algorithm-specific settings. Furthermore, it supports functional properties to dynamically adjust compression parameters based on response type, size, and the full Koa context, aiming to optimize network transfer sizes by offloading content encoding from application logic.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use `require()` in an ES Module context (e.g., in a `.mjs` file or when `"type": "module"` is set in `package.json`).fixChange your import statement to `import compress from 'koa-compress';` to use ES Module syntax. Ensure `import Koa from 'koa';` and other imports are also using ESM. -
ERR_INVALID_ARG_TYPE: The 'flush' argument must be one of type number. Received type undefined
cause Incorrectly providing the `flush` option for `gzip` or `deflate` settings, often due to not importing `zlib.constants` or using an undefined value.fixEnsure you import `constants` from Node.js's `zlib` module: `import { constants as zlibConstants } from 'zlib';`. Then, use these constants for flush options: `gzip: { flush: zlibConstants.Z_SYNC_FLUSH }`. -
Expected 'options.br' to be object or function but got false
cause Passing a boolean value (`false`) to an encoding option (e.g., `br`) when the `options[encoding]` property expects an object for configuration or a function for dynamic options, and the middleware expects an explicit object for that type of configuration.fixTo disable an encoding like `br`, simply omit it from the `compress` options object or explicitly set `br: false`. If you intend to provide options, use an object: `br: { quality: 4 }`. The error message in this specific form indicates a misunderstanding or a type mismatch with expected configuration. -
Response is not compressed (e.g., 'Content-Encoding' header missing) even when expected.
cause The response's MIME type does not match the `filter` predicate, or the response size is below the `threshold` configured in the middleware options.fixReview the `filter` function to ensure it correctly identifies the `ctx.type` for compression. Check the `threshold` value against `ctx.response.length` (or `ctx.body` size) to confirm the response is large enough. You can also temporarily force compression with `ctx.compress = true;` for debugging specific routes.
Warnings
- breaking The default behavior for clients sending no `Accept-Encoding` header changed in `v5.0.0`. It now defaults to `'identity'` (no compression) instead of the HTTP spec-compliant `'*'` (any encoding). This can affect debugging tools like `curl` that often omit `Accept-Encoding` by default.
- breaking Version 4.0.0 dropped support for Node.js versions below 10. Additionally, the way options were passed to compression functions (like `gzip`, `deflate`, `br`) changed significantly. Previous configurations may no longer be valid.
- gotcha `zstandard` (zstd) compression is only supported natively in specific Node.js versions: `v22.15.0` (LTS) or `v23.8.0` (Current) and above. If your Node.js version is older, `zstd` compression will be silently skipped, even if configured.
- gotcha When configuring `gzip` or `deflate` options, especially the `flush` property, direct numeric values or incorrect string literals can lead to errors. Node.js's `zlib` module expects specific `constants` for these settings.
Install
-
npm install koa-compress -
yarn add koa-compress -
pnpm add koa-compress
Imports
- compress
const compress = require('koa-compress');import compress from 'koa-compress';
- compress
import { compress } from 'koa-compress';const compress = require('koa-compress'); - CompressOptions
import type { CompressOptions } from 'koa-compress'; - constants
import * as zlib from 'zlib'; const flush = zlib.Z_SYNC_FLUSH;
import { constants as zlibConstants } from 'zlib';
Quickstart
import Koa from 'koa';
import compress from 'koa-compress';
import { constants as zlibConstants } from 'zlib'; // Required for zlib options
const app = new Koa();
// Example of how to manually control compression for specific routes or conditions
app.use(async (ctx, next) => {
// Forcing compression (bypasses filter)
// ctx.compress = true;
// Disabling compression
// ctx.compress = false;
// Overriding options for a specific response
// ctx.compress = { threshold: 10, gzip: { level: 9 } };
await next();
});
app.use(
compress({
// Predicate function to determine if a response should be compressed
filter(content_type) {
return /text|json|javascript/i.test(content_type || '');
},
// Minimum response size in bytes to trigger compression
threshold: 2048,
gzip: {
flush: zlibConstants.Z_SYNC_FLUSH, // Use constants from Node's zlib
level: 6 // Default gzip compression level
},
deflate: {
flush: zlibConstants.Z_SYNC_FLUSH
},
// Brotli (br) is enabled by default. Set to false to disable or provide options.
// br: false,
// br: { quality: 4 }, // Example: Lower brotli quality for faster compression
// Zstandard (zstd) is automatically enabled if supported by Node.js runtime.
// zstd: { level: 1 }, // Example: Zstd compression level
defaultEncoding: 'identity' // When client sends no Accept-Encoding header
}),
);
// A route that serves a compressible body
app.use((ctx) => {
ctx.type = 'text/plain';
// Ensure body size exceeds the threshold for compression to apply
ctx.body = 'This is a long string that will be compressed by koa-compress middleware if the client supports it and the size exceeds the threshold.'
.repeat(50);
});
const port = 3000;
app.listen(port, () => {
console.log(`Koa server running on http://localhost:${port}`);
console.log('Test compression: curl -H "Accept-Encoding: gzip" -I http://localhost:3000');
});