{"id":13836102,"url":"https://github.com/fastify/fastify-compress","last_synced_at":"2025-05-14T16:12:23.296Z","repository":{"id":26847766,"uuid":"110041702","full_name":"fastify/fastify-compress","owner":"fastify","description":"Fastify compression utils","archived":false,"fork":false,"pushed_at":"2025-05-01T14:14:38.000Z","size":411,"stargazers_count":210,"open_issues_count":12,"forks_count":48,"subscribers_count":20,"default_branch":"main","last_synced_at":"2025-05-12T12:07:02.170Z","etag":null,"topics":["brotli","compression","deflate","fastify","fastify-plugin","gzip"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@fastify/compress","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fastify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"fastify","open_collective":"fastify"}},"created_at":"2017-11-08T23:19:05.000Z","updated_at":"2025-05-08T06:13:58.000Z","dependencies_parsed_at":"2024-01-25T20:02:11.809Z","dependency_job_id":"f753eff2-a492-44a4-a0b9-1ceb9de97ece","html_url":"https://github.com/fastify/fastify-compress","commit_stats":{"total_commits":325,"total_committers":50,"mean_commits":6.5,"dds":0.8215384615384616,"last_synced_commit":"488a28d25f71ce7c674d4b6bf9b4fc3ee81c9f72"},"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-compress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-compress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-compress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-compress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fastify","download_url":"https://codeload.github.com/fastify/fastify-compress/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253943543,"owners_count":21988286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brotli","compression","deflate","fastify","fastify-plugin","gzip"],"created_at":"2024-08-04T15:00:35.604Z","updated_at":"2025-05-14T16:12:23.274Z","avatar_url":"https://github.com/fastify.png","language":"JavaScript","readme":"# @fastify/compress\n\n[![CI](https://github.com/fastify/fastify-compress/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fastify-compress/actions/workflows/ci.yml)\n[![NPM version](https://img.shields.io/npm/v/@fastify/compress.svg?style=flat)](https://www.npmjs.com/package/@fastify/compress)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)\n\nAdds compression utils to [the Fastify `reply` object](https://fastify.dev/docs/latest/Reference/Reply/#reply) and a hook to decompress requests payloads.\nSupports `gzip`, `deflate`, and `brotli`.\n\n\u003e 🛈 Note: In large-scale scenarios, use a proxy like Nginx to handle response compression.\n\n\u003e ⚠ Warning: Since `@fastify/compress` version 4.x, payloads compressed with the `zip` algorithm are not automatically uncompressed. This plugin focuses on response compression, and `zip` is not in the [IANA Table of Content Encodings](https://www.iana.org/assignments/http-parameters/http-parameters.xml#content-coding).\n\n## Install\n```\nnpm i @fastify/compress\n```\n\n### Compatibility\n| Plugin version | Fastify version |\n| ---------------|-----------------|\n| `\u003e=8.x`        | `^5.x`          |\n| `\u003e=6.x \u003c8.x`   | `^4.x`          |\n| `\u003e=3.x \u003c6.x`   | `^3.x`          |\n| `^2.x`         | `^2.x`          |\n| `\u003e=0.x \u003c2.x`   | `^1.x`          |\n\n\nPlease note that if a Fastify version is out of support, then so are the corresponding versions of this plugin\nin the table above.\nSee [Fastify's LTS policy](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details.\n\n\n## Usage - Compress replies\n\nThis plugin adds two functionalities to Fastify: a compress utility and a global compression hook.\n\nCurrently, the following encoding tokens are supported, using the first acceptable token in this order:\n\n1. `br`\n2. `gzip`\n3. `deflate`\n4. `*` (no preference — `@fastify/compress` will use `gzip`)\n5. `identity` (no compression)\n\nIf an unsupported encoding is received or the `'accept-encoding'` header is missing, the payload will not be compressed.\nTo return an error for unsupported encoding, use the `onUnsupportedEncoding` option.\n\nThe plugin compresses payloads based on `content-type`. If absent, it assumes `application/json`.\n\n### Global hook\nThe global compression hook is enabled by default. To disable it, pass `{ global: false }`:\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { global: false }\n)\n```\nFastify encapsulation can be used to set global compression but run it only in a subset of routes by wrapping them inside a plugin.\n\n\u003e 🛈 Note: If using `@fastify/compress` plugin together with `@fastify/static` plugin, `@fastify/compress` must be registered (with *global hook*) **before** registering `@fastify/static`.\n\n### Per Route options\nDifferent compression options can be specified per route using the `compress` options in the route's configuration.\nSetting `compress: false` on any route will disable compression on the route even if global compression is enabled.\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { global: false }\n)\n\n// only compress if the payload is above a certain size and use brotli\nfastify.get('/custom-route', {\n  compress: {\n    inflateIfDeflated: true,\n    threshold: 128,\n    zlib: {\n      createBrotliCompress: () =\u003e createYourCustomBrotliCompress(),\n      createGzip: () =\u003e createYourCustomGzip(),\n      createDeflate: () =\u003e createYourCustomDeflate()\n    }\n  }, (req, reply) =\u003e {\n    // ...\n  })\n```\n\n### `reply.compress`\nThis plugin adds a `compress` method to `reply` that compresses a stream or string based on the `accept-encoding` header. If a JS object is passed, it will be stringified to JSON.\n\nThe `compress` method uses per-route parameters if configured, otherwise it uses global parameters.\n\n```js\nimport fs from 'node:fs'\nimport fastify from 'fastify'\n\nconst app = fastify()\nawait app.register(import('@fastify/compress'), { global: false })\n\napp.get('/', (req, reply) =\u003e {\n  reply\n    .type('text/plain')\n    .compress(fs.createReadStream('./package.json'))\n})\n\nawait app.listen({ port: 3000 })\n```\n\n## Compress Options\n\n### threshold\nThe minimum byte size for response compression. Defaults to `1024`.\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { threshold: 2048 }\n)\n```\n### customTypes\n[mime-db](https://github.com/jshttp/mime-db) determines if a `content-type` should be compressed. Additional content types can be compressed via regex or a function.\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { customTypes: /x-protobuf$/ }\n)\n```\n\nor\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { customTypes: contentType =\u003e contentType.endsWith('x-protobuf') }\n)\n```\n\n### onUnsupportedEncoding\nSet `onUnsupportedEncoding(encoding, request, reply)` to send a custom error response for unsupported encoding. The function can modify the reply and return a `string | Buffer | Stream | Error` payload.\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  {\n    onUnsupportedEncoding: (encoding, request, reply) =\u003e {\n      reply.code(406)\n      return 'We do not support the ' + encoding + ' encoding.'\n    }\n  }\n)\n```\n\n### Disable compression by header\nResponse compression can be disabled by an `x-no-compression` header in the request.\n\n### Inflate pre-compressed bodies for clients that do not support compression\nOptional feature to inflate pre-compressed data if the client does not include one of the supported compression types in its `accept-encoding` header.\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { inflateIfDeflated: true }\n)\n\nfastify.get('/file', (req, reply) =\u003e\n  // will inflate the file  on the way out for clients\n  // that indicate they do not support compression\n  reply.send(fs.createReadStream('./file.gz')))\n```\n\n### Customize encoding priority\nBy default, `@fastify/compress` prioritizes compression as described [here](#usage). Change this by passing an array of compression tokens to the `encodings` option:\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  // Only support gzip and deflate, and prefer deflate to gzip\n  { encodings: ['deflate', 'gzip'] }\n)\n```\n\n### brotliOptions and zlibOptions\nCompression can be tuned with `brotliOptions` and `zlibOptions`, which are passed directly to native node `zlib` methods. See [class definitions](https://nodejs.org/api/zlib.html#zlib_class_options).\n\n```js\n  server.register(fastifyCompress, {\n    brotliOptions: {\n      params: {\n        [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT, // useful for APIs that primarily return text\n        [zlib.constants.BROTLI_PARAM_QUALITY]: 4, // default is 4, max is 11, min is 0\n      },\n    },\n    zlibOptions: {\n      level: 6, // default is typically 6, max is 9, min is 0\n    }\n  });\n```\n\n### Manage `Content-Length` header removal with removeContentLengthHeader\nBy default, `@fastify/compress` removes the reply `Content-Length` header. Change this by setting `removeContentLengthHeader` to `false` globally or per route.\n\n```js\n  // Global plugin scope\n  await server.register(fastifyCompress, { global: true, removeContentLengthHeader: false });\n\n  // Route-specific scope\n  fastify.get('/file', {\n    compress: { removeContentLengthHeader: false }\n  }, (req, reply) =\u003e\n    reply.compress(fs.createReadStream('./file.gz'))\n  )\n```\n\n## Usage - Decompress request payloads\nThis plugin adds a `preParsing` hook to decompress the request payload based on the `content-encoding` request header.\n\nCurrently, the following encoding tokens are supported:\n\n1. `br`\n2. `gzip`\n3. `deflate`\n\nIf an unsupported encoding or invalid payload is received, the plugin throws an error.\n\nIf the request header is missing, the plugin yields to the next hook.\n\n### Global hook\n\nThe global request decompression hook is enabled by default. To disable it, pass `{ global: false }`:\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { global: false }\n)\n```\n\nFastify encapsulation can be used to set global decompression but run it only in a subset of routes by wrapping them inside a plugin.\n\n### Per Route options\n\nSpecify different decompression options per route using the `decompress` options in the route's configuration.\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  { global: false }\n)\n\n// Always decompress using gzip\nfastify.get('/custom-route', {\n  decompress: {\n    forceRequestEncoding: 'gzip',\n    zlib: {\n      createBrotliDecompress: () =\u003e createYourCustomBrotliDecompress(),\n      createGunzip: () =\u003e createYourCustomGunzip(),\n      createInflate: () =\u003e createYourCustomInflate()\n    }\n  }\n}, (req, reply) =\u003e {\n    // ...\n  })\n```\n\n### requestEncodings\n\nBy default, `@fastify/compress` accepts all encodings specified [here](#usage). Change this by passing an array of compression tokens to the `requestEncodings` option:\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  // Only support gzip\n  { requestEncodings: ['gzip'] }\n)\n```\n\n### forceRequestEncoding\n\nBy default, `@fastify/compress` chooses the decompression algorithm based on the `content-encoding` header.\n\nOne algorithm can be forced, and the header ignored, by providing the `forceRequestEncoding` option.\n\nIf the request payload is not compressed, `@fastify/compress` will try to decompress, resulting in an error.\n\n### onUnsupportedRequestEncoding\n\nThe response error can be customized for unsupported request payload encoding by setting `onUnsupportedEncoding(request, encoding)` to a function that returns an error.\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  {\n     onUnsupportedRequestEncoding: (request, encoding) =\u003e {\n      return {\n        statusCode: 415,\n        code: 'UNSUPPORTED',\n        error: 'Unsupported Media Type',\n        message: 'We do not support the ' + encoding + ' encoding.'\n      }\n    }\n  }\n)\n```\n\n### onInvalidRequestPayload\n\nThe response error can be customized for undetectable request payloads by setting `onInvalidRequestPayload(request, encoding)` to a function that returns an error.\n\n```js\nawait fastify.register(\n  import('@fastify/compress'),\n  {\n    onInvalidRequestPayload: (request, encoding, error) =\u003e {\n      return {\n        statusCode: 400,\n        code: 'BAD_REQUEST',\n        error: 'Bad Request',\n        message: 'This is not a valid ' + encoding + ' encoded payload: ' + error.message\n      }\n    }\n  }\n)\n```\n\n## Acknowledgments\n\nPast sponsors:\n\n- [LetzDoIt](http://www.letzdoitapp.com/)\n\n## License\n\nLicensed under [MIT](./LICENSE).\n","funding_links":["https://github.com/sponsors/fastify","https://opencollective.com/fastify"],"categories":["\u003ch2 align=\"center\"\u003eAwesome Fastify\u003c/h2\u003e","JavaScript"],"sub_categories":["\u003ch2 align=\"center\"\u003eEcosystem\u003c/h2\u003e"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Ffastify-compress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffastify%2Ffastify-compress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Ffastify-compress/lists"}