{"id":16020,"library":"etag","title":"HTTP ETag Generator","description":"The `etag` package is a minimalist, RFC 7232-compliant utility for generating HTTP ETags in Node.js applications. It currently maintains a stable version 1.8.1 and has a low release cadence, reflecting its maturity and focused scope. The library supports generating strong ETags for strings and `Buffer`s, and weak ETags by default for `fs.Stats` objects, with an option to override this behavior. Key differentiators include its strict adherence to the HTTP ETag specification, performance optimization for various entity sizes, and a history of robust integration within the `jshttp` ecosystem, often used by popular HTTP frameworks like Express. It prioritizes correctness and efficiency in ETag calculation, having evolved through several hashing algorithm updates to improve security and performance.","status":"maintenance","version":"1.8.1","language":"javascript","source_language":"en","source_url":"https://github.com/jshttp/etag","tags":["javascript","etag","http","res"],"install":[{"cmd":"npm install etag","lang":"bash","label":"npm"},{"cmd":"yarn add etag","lang":"bash","label":"yarn"},{"cmd":"pnpm add etag","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The 'etag' package exports a default function. Named imports like `import { etag } from 'etag'` will fail in ESM environments.","wrong":"import { etag } from 'etag';","symbol":"etag","correct":"import etag from 'etag';"},{"note":"This is the original CommonJS import style. Modern Node.js projects configured for ESM should use `import etag from 'etag';`.","wrong":"import etag from 'etag';","symbol":"etag (CommonJS)","correct":"const etag = require('etag');"}],"quickstart":{"code":"import etag from 'etag';\n\n// Scenario 1: Generating a strong ETag for a string entity\nconst stringBody = '<h1>Hello World!</h1>';\nconst strongStringEtag = etag(stringBody);\nconsole.log(`Strong ETag for string: ${strongStringEtag}`);\n\n// Scenario 2: Generating a weak ETag for a string entity\nconst weakStringEtag = etag(stringBody, { weak: true });\nconsole.log(`Weak ETag for string: ${weakStringEtag}`);\n\n// Scenario 3: Generating a strong ETag for a Buffer entity\nconst bufferBody = Buffer.from('<p>This is a buffered response.</p>');\nconst strongBufferEtag = etag(bufferBody);\nconsole.log(`Strong ETag for buffer: ${strongBufferEtag}`);\n\n// Scenario 4: Generating a weak ETag for a Buffer entity\nconst weakBufferEtag = etag(bufferBody, { weak: true });\nconsole.log(`Weak ETag for buffer: ${weakBufferEtag}`);\n\n// Scenario 5: How it's typically used in an HTTP response (conceptual)\n// (Imagine `res` is an HTTP response object in a web framework)\n// const res = {\n//   setHeader: (name, value) => console.log(`Setting Header: ${name}: ${value}`)\n// };\n// const responseBody = 'Some dynamic content';\n// res.setHeader('ETag', etag(responseBody));\n// console.log(\"Header set for responseBody.\");","lang":"javascript","description":"Demonstrates generating strong and weak ETags for string and Buffer entities, illustrating typical usage patterns in Node.js."},"warnings":[{"fix":"Be aware that existing client caches relying on pre-1.8.0 ETags will likely become stale. If strict ETag consistency across deployments or upgrades is critical, consider implementing cache-busting strategies or re-evaluating caching policies.","message":"In `v1.8.0`, the underlying hashing algorithm for ETag generation was changed from MD5 to SHA1. This means ETags generated by `v1.8.0` and later will differ from those generated by prior versions for the same entity, potentially invalidating existing client caches.","severity":"breaking","affected_versions":">=1.8.0"},{"fix":"Similar to the `v1.8.0` change, this also impacts ETag values. Ensure client caches are appropriately handled or invalidated if upgrading from versions prior to 1.7.0. Note that the MD5 algorithm used in this range was later updated to SHA1 in `v1.8.0`.","message":"Version `v1.7.0` introduced significant changes to ETag generation logic. This included always incorporating entity length, generating non-Stats ETags using only MD5 (CRC32 removed), and removing base64 padding. These changes result in different ETag values compared to `v1.6.0` and earlier.","severity":"breaking","affected_versions":">=1.7.0 <1.8.0"},{"fix":"Always pass `{ weak: true }` or `{ weak: false }` to the `etag()` function if you need to override the default strong/weak behavior for specific entity types or to ensure consistent behavior.","message":"By default, `etag` generates strong ETags for strings and `Buffer`s, but a weak ETag for `fs.Stats` objects. If you require a strong ETag for `fs.Stats` or a weak ETag for strings/buffers, you must explicitly set the `options.weak` flag.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure the first argument passed to `etag()` is a `string`, a `Buffer` instance, or an `fs.Stats` object (or a compatible mock object mimicking properties like `mtime`, `size`, `ino`).","cause":"The `etag` function was called with an unsupported data type for the `entity` argument (e.g., `null`, `undefined`, a number, or a complex object that isn't `fs.Stats`).","error":"TypeError: entity must be a string, Buffer or fs.Stats"},{"fix":"To guarantee consistent ETag generation, ensure that the `etag` package version is locked and identical across all deployment environments. Use package manager commands like `npm ci` or `yarn install --frozen-lockfile` to enforce exact dependency versions.","cause":"This issue typically arises when different versions of the `etag` package are used across environments. Past updates to `etag` have changed the underlying hashing algorithms (e.g., from MD5 to SHA1) or ETag generation logic, leading to different output for the same input.","error":"ETags generated are inconsistent between different deployments or environments."}],"ecosystem":"npm"}