Automatically generate etags for HTTP responses, for Fastify
85
stars
191
commits
JavaScript
primary language
Aug 6, 2026
updated
A plugin for Fastify that automatically generates HTTP ETags according to RFC2616-sec13.
The plugin can optionally send a 304 status code when an ETag matches the if-none-match header.
npm i @fastify/etag
| Plugin version | Fastify version |
|---|---|
>=6.x | ^5.x |
>=4.x <6.x | ^4.x |
^3.x | ^3.x |
>=1.x <3.x | ^2.x |
Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin in the table above. See Fastify's LTS policy for more details.
'use strict'
const Fastify = require('fastify')
const Etag = require('@fastify/etag')
const app = Fastify()
app.register(Etag)
app.get('/', async (req, reply) => {
return { hello: 'world' }
})
app.get('/manual-etag', async (req, reply) => {
// This will disable automatic ETag generation
// It will still return a 304 if the ETag matches
reply.header('etag', '"foobar"')
return 'world'
})
app.listen(3000)
algorithm: all hashing algorithms the Node.js crypto module supports. Default: 'sha1'. ('fnv1a' is deprecated; use hashFn: Etag.fnv1a instead.)hashFn: function used to generate ETags (called with string or Buffer payload; return an unquoted hash string). When provided, algorithm option will be ignored. Default: undefined.weak: generates weak ETags by default. Default: false.'use strict'
const Fastify = require('fastify')
const Etag = require('@fastify/etag')
const app = Fastify()
app.register(Etag, {
hashFn: Etag.fnv1a // Use fnv1a provided by @fastify/etag
})
app.get('/', async (req, reply) => {
return { hello: 'world' }
})
app.get('/manual-etag', async (req, reply) => {
// This will disable automatic ETag generation
// It will still return a 304 if the ETag matches
reply.header('etag', '"foobar"')
return 'world'
})
app.listen(3000)
By default, the plugin sends a 304 status code when the ETag is equal to the Etag specified by the if-none-match request header.
This is often the desired behavior, but can be disabled by setting replyWith304: false.
The fnv1a logic was forked from Travis Webb (@tjwebb)'s https://github.com/tjwebb/fnv-plus, the actual implementation is contributed to fnv-plus by @desudesutalk in https://github.com/tjwebb/fnv-plus/pull/9, and adapted by @SukkaW to support buffers.
Generating an etag will always be slower than not generating an etag. The generation speed also depends on the payload size and type (buffer or string):
'fnv1a''md5''sha1' (default)Licensed under MIT.
JavaScript
98.2%
TypeScript
1.8%
Automatically generate etags for HTTP responses, for Fastify
85
stars
191
commits
JavaScript
primary language
Aug 6, 2026
updated
A plugin for Fastify that automatically generates HTTP ETags according to RFC2616-sec13.
The plugin can optionally send a 304 status code when an ETag matches the if-none-match header.
npm i @fastify/etag
| Plugin version | Fastify version |
|---|---|
>=6.x | ^5.x |
>=4.x <6.x | ^4.x |
^3.x | ^3.x |
>=1.x <3.x | ^2.x |
Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin in the table above. See Fastify's LTS policy for more details.
'use strict'
const Fastify = require('fastify')
const Etag = require('@fastify/etag')
const app = Fastify()
app.register(Etag)
app.get('/', async (req, reply) => {
return { hello: 'world' }
})
app.get('/manual-etag', async (req, reply) => {
// This will disable automatic ETag generation
// It will still return a 304 if the ETag matches
reply.header('etag', '"foobar"')
return 'world'
})
app.listen(3000)
algorithm: all hashing algorithms the Node.js crypto module supports. Default: 'sha1'. ('fnv1a' is deprecated; use hashFn: Etag.fnv1a instead.)hashFn: function used to generate ETags (called with string or Buffer payload; return an unquoted hash string). When provided, algorithm option will be ignored. Default: undefined.weak: generates weak ETags by default. Default: false.'use strict'
const Fastify = require('fastify')
const Etag = require('@fastify/etag')
const app = Fastify()
app.register(Etag, {
hashFn: Etag.fnv1a // Use fnv1a provided by @fastify/etag
})
app.get('/', async (req, reply) => {
return { hello: 'world' }
})
app.get('/manual-etag', async (req, reply) => {
// This will disable automatic ETag generation
// It will still return a 304 if the ETag matches
reply.header('etag', '"foobar"')
return 'world'
})
app.listen(3000)
By default, the plugin sends a 304 status code when the ETag is equal to the Etag specified by the if-none-match request header.
This is often the desired behavior, but can be disabled by setting replyWith304: false.
The fnv1a logic was forked from Travis Webb (@tjwebb)'s https://github.com/tjwebb/fnv-plus, the actual implementation is contributed to fnv-plus by @desudesutalk in https://github.com/tjwebb/fnv-plus/pull/9, and adapted by @SukkaW to support buffers.
Generating an etag will always be slower than not generating an etag. The generation speed also depends on the payload size and type (buffer or string):
'fnv1a''md5''sha1' (default)Licensed under MIT.
JavaScript
98.2%
TypeScript
1.8%