remix/middleware/compression
Response compression middleware for Remix. It negotiates br, gzip, and deflate from Accept-Encoding and applies sensible defaults for when compression is useful.
Features
- Encoding Negotiation - Selects the best supported encoding from
Accept-Encoding - Compression Guards - Skips already-compressed responses and range-enabled responses
- Size Thresholds - Configurable minimum response size for compression
- MIME Filtering - Compresses only content types likely to benefit
Installation
npm i remixUsage
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
let router = createRouter({
middleware: [compression()],
})The middleware will automatically compress responses for compressible MIME types when:
- The client supports compression (
Accept-Encodingheader with a supported encoding) - The response is large enough to benefit from compression (≥1024 bytes if
Content-Lengthis present, by default) - The response hasn't already been compressed
- The response doesn't advertise range support (
Accept-Ranges: bytes)
Threshold
Default: 1024 (only enforced if Content-Length is present)
Set the minimum response size in bytes to compress:
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
let router = createRouter({
middleware: [
compression({
threshold: 2048, // Only compress responses ≥2KB
}),
],
})Encodings
Default: ['br', 'gzip', 'deflate']
Customize which compression algorithms to support:
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
let router = createRouter({
middleware: [
compression({
encodings: ['br', 'gzip'], // Only use Brotli and Gzip
}),
],
})The encodings option can also be a function that receives the response:
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
let router = createRouter({
middleware: [
compression({
encodings: (response) => {
// Use different encodings for server-sent events
let contentType = response.headers.get('Content-Type')
return contentType?.startsWith('text/event-stream;')
? ['gzip', 'deflate']
: ['br', 'gzip', 'deflate']
},
}),
],
})Filter Media Type
Default: Uses isCompressibleMimeType() from remix/mime
You can customize this behavior with the filterMediaType option:
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
import { isCompressibleMimeType } from 'remix/mime'
let router = createRouter({
middleware: [
compression({
filterMediaType(mediaType) {
// Add a custom media type to the default compressible list
return isCompressibleMimeType(mediaType) || mediaType === 'application/vnd.example+data'
},
}),
],
})Compression Options
Default: Uses Node.js defaults for zlib and Brotli, with streaming-safe flush handling for HTML and server-sent events.
For text/html and text/event-stream responses, gzip and deflate use Z_SYNC_FLUSH, while Brotli uses BROTLI_OPERATION_FLUSH. This keeps each response chunk available to clients without waiting for the stream to finish. Explicit flush options override these defaults.
You can pass options to the underlying Node.js zlib and brotli compressors for fine-grained control:
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
import { zlib } from 'node:zlib'
let router = createRouter({
middleware: [
compression({
zlib: {
level: 6,
},
brotli: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 4,
},
},
}),
],
})Like encodings, both zlib and brotli options can also be functions that receive the response:
import zlib from 'node:zlib'
import { createRouter } from 'remix/router'
import { compression } from 'remix/middleware/compression'
let router = createRouter({
middleware: [
compression({
brotli: (response) => {
let contentType = response.headers.get('Content-Type')
return {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: contentType?.startsWith('text/html;') ? 4 : 11,
},
}
},
}),
],
})Related Packages
remix/router- Router for the web Fetch APIremix/mime- MIME type utilitiesremix/response- Response helpers
License
MIT