Node.js HTTP Compression Middleware
The `compression` package provides middleware for Node.js, primarily designed for Express applications, to automatically compress HTTP responses. It supports common compression algorithms including gzip, deflate, and brotli. The current stable version is 1.8.1. Releases occur on an as-needed basis, typically for dependency updates, minor bug fixes, or to incorporate newer Node.js features, indicating an active maintenance status rather than rapid feature development. Key differentiators include its seamless integration into the Express middleware stack, configurable compression options (like level, chunk size, and memory level), and a flexible `filter` function to control which responses are compressed. It leverages Node.js's built-in `zlib` module for compression capabilities and ensures compliance with HTTP standards by respecting `Cache-Control: no-transform` directives.
Common errors
-
Error: Brotli: Unsupported encoding
cause Attempting to use Brotli compression (`br`) in a Node.js environment that does not support it (versions older than v10.16.0 or v11.7.0).fixUpgrade your Node.js version to at least v10.16.0 or v11.7.0, or remove the `brotli` options from the `compression` middleware configuration. -
TypeError: app.use is not a function
cause The `compression` middleware is being applied to an object that is not an Express application instance or router, or `express()` was not correctly called.fixEnsure that `app` is a valid Express application instance (e.g., `const app = express();`) or an Express router, and that `app.use()` is called correctly with the middleware. -
Warning: Can't set headers after they are sent.
cause This warning can occur if another middleware or route handler attempts to modify response headers after `compression` (or another middleware) has already sent headers to the client, typically because the response body has started streaming.fixReview the order of your middleware and ensure that all header-modifying operations occur before the `compression` middleware and before any part of the response body is flushed.
Warnings
- gotcha Brotli compression (encoding 'br') is only supported in Node.js versions v11.7.0 and later, or v10.16.0 and later. Attempting to use Brotli options on older Node.js versions will result in an unsupported encoding error or silent failure to compress.
- gotcha The middleware will explicitly skip compression if the `Cache-Control` response header contains the `no-transform` directive. This is standard HTTP behavior to prevent intermediaries from altering content, but can sometimes lead to unexpected uncompressed responses if not intended.
- gotcha The default `filter` function relies on the `compressible` package to determine if a `Content-Type` is suitable for compression. If you're serving custom or unusual `Content-Type` headers that you wish to compress, you may need to provide a custom `filter` function.
- breaking While not a direct breaking change from `compression` itself, Node.js `zlib` API constants used for options (like `Z_DEFAULT_COMPRESSION`) are available directly on `zlib` module from Node.js v11.0.0+. For older Node.js versions, they might be nested or less consistently exposed, potentially affecting options configuration.
Install
-
npm install compression -
yarn add compression -
pnpm add compression
Imports
- compression
import { compression } from 'compression';import compression from 'compression';
- compression
const compression = require('compression'); - CompressionOptions
import { CompressionOptions } from 'compression';import type { CompressionOptions } from 'compression';
Quickstart
import express from 'express';
import compression from 'compression';
const app = express();
// Use the compression middleware
app.use(compression({
level: 6, // Default compression level
filter: (req, res) => {
if (req.headers['x-no-compression']) {
// don't compress responses with this header
return false;
}
// fallback to standard filter function
return compression.filter(req, res);
},
brotli: { // Brotli specific options, requires Node.js >= 10.16.0 or >= 11.7.0
params: {
[compression.constants.BROTLI_PARAM_QUALITY]: 4
}
}
}));
app.get('/', (req, res) => {
res.type('text/html');
res.send(`
<!DOCTYPE html>
<html>
<head><title>Compressed Page</title></head>
<body>
<h1>Hello, Compressed World!</h1>
<p>This is a lengthy paragraph to ensure the response body is large enough to benefit from compression. The compression middleware will automatically compress this content if the client supports it.</p>
<p>Current time: ${new Date().toISOString()}</p>
<p>You can inspect the 'Content-Encoding' header in your browser's developer tools or by using 'curl -H "Accept-Encoding: gzip" http://localhost:3000 -v' to confirm compression.</p>
</body>
</html>
`);
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Try visiting in your browser or using curl -H "Accept-Encoding: gzip" http://localhost:3000 -v');
});