{"id":17106,"library":"koa-etag","title":"Koa ETag Middleware","description":"koa-etag is a Koa middleware package designed to provide ETag support for HTTP responses, leveraging the `etag` library to automatically generate ETag headers. This functionality is crucial for enhancing caching efficiency, as it allows clients (browsers, proxies) to conditionally request resources, thereby reducing bandwidth consumption and server load. The current stable version is 5.0.0, which notably features a complete rewrite in TypeScript, offering both ESM and CJS bundles, and requiring Node.js 18+. While there isn't a strict, frequent release cadence, major updates like v5.0.0 represent significant overhauls. Its primary differentiator is its seamless integration within the Koa ecosystem, typically working in conjunction with `koa-conditional-get` to enable full HTTP conditional GET support. However, it is important to note that the package's README strongly advises migrating to `@koa/etag` (v5+) as `koa-etag` is slated for deprecation in its next major release.","status":"maintenance","version":"5.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/koajs/etag","tags":["javascript","koa","middleware","cache","caching","etag","file","static","sendfile","typescript"],"install":[{"cmd":"npm install koa-etag","lang":"bash","label":"npm"},{"cmd":"yarn add koa-etag","lang":"bash","label":"yarn"},{"cmd":"pnpm add koa-etag","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for the Koa framework.","package":"koa","optional":false},{"reason":"Required for full conditional GET support, working alongside koa-etag.","package":"koa-conditional-get","optional":false},{"reason":"Necessary for handling compressed responses; must be applied before koa-etag.","package":"koa-compress","optional":false}],"imports":[{"note":"Since v5, the package is ESM-first with CJS interop, exposing the middleware as a default export. Named imports are incorrect.","wrong":"import { etag } from 'koa-etag';","symbol":"etag","correct":"import etag from 'koa-etag';"},{"note":"For CommonJS environments, the middleware is the default export. Destructuring is incorrect.","wrong":"const { etag } = require('koa-etag');","symbol":"etag (CommonJS)","correct":"const etag = require('koa-etag');"},{"note":"Available since v5, used for configuring the middleware with TypeScript.","symbol":"KoaEtagOptions (TypeScript type)","correct":"import type { KoaEtagOptions } from 'koa-etag';"}],"quickstart":{"code":"const Koa = require('koa');\nconst etag = require('koa-etag');\nconst conditional = require('koa-conditional-get');\nconst compress = require('koa-compress');\n\nconst app = new Koa();\n\n// compress must be used before conditional and etag for correct ETag calculation\napp.use(compress());\n\n// etag works together with conditional-get for full HTTP caching support\napp.use(conditional());\napp.use(etag());\n\napp.use(function (ctx) {\n  ctx.body = 'Hello World';\n});\n\napp.listen(3000);\n\nconsole.log('Server listening on port 3000');","lang":"javascript","description":"This example demonstrates how to set up `koa-etag` in a Koa application, showing its typical usage alongside `koa-conditional-get` and `koa-compress`."},"warnings":[{"fix":"Replace `npm install koa-etag` with `npm install @koa/etag` and update import paths accordingly. The API is largely identical.","message":"The `koa-etag` package is in maintenance mode and will be formally deprecated in its next major release. Users are strongly advised to migrate to the `@koa/etag` package for continued support, bug fixes, and future feature updates, as it is the direct successor and recommended alternative.","severity":"deprecated","affected_versions":">=5.0.0"},{"fix":"Ensure `app.use(compress())` is called prior to `app.use(conditional())` and `app.use(etag())` in your Koa application setup.","message":"For correct ETag generation and response caching, the `koa-compress` middleware must be applied *before* `koa-conditional-get` and `koa-etag` in the middleware chain. Applying compression after ETag calculation will result in mismatched ETags for compressed content.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Upgrade your Node.js runtime environment to version 18 or later to use `koa-etag` v5.x.","message":"Version 5.x of `koa-etag` dropped support for older Node.js versions. It now explicitly requires Node.js 18 or higher due to modern language features and tooling updates.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"For CommonJS, use `const etag = require('koa-etag');`. For ESM, use `import etag from 'koa-etag';`. Avoid named imports like `import { etag } from 'koa-etag';`.","message":"Version 5.x was rewritten in TypeScript and bundled for both ESM and CJS. While `v5.0.2` improved CJS interop, incorrect import statements (e.g., named imports for default exports) can lead to errors.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"For CommonJS, use `const etag = require('koa-etag');`. For ESM, use `import etag from 'koa-etag';` to correctly import the default middleware function.","cause":"This error typically occurs when attempting to import `koa-etag` using a named import syntax (e.g., `import { etag } from 'koa-etag'`) or destructuring with `require` (`const { etag } = require('koa-etag')`), despite the package providing a default export.","error":"TypeError: etag is not a function"},{"fix":"Ensure both `koa-conditional-get` and `koa-etag` are applied, and crucially, `app.use(compress())` must be called before `app.use(conditional())` and `app.use(etag())`.","cause":"A common cause is `koa-conditional-get` not being installed or used, or `koa-compress` being placed after `koa-etag` in the middleware stack. `koa-etag` only *generates* the ETag; `koa-conditional-get` handles the client-side conditional requests, and `koa-compress` must run first to ensure the ETag is calculated on the final (compressed) body.","error":"ETag headers are missing or not functioning correctly, despite `koa-etag` being installed."}],"ecosystem":"npm","meta_description":null}