HTTP Response Freshness Testing
The `fresh` package (version 0.5.2, last published in September 2017) is a minimalist Node.js utility designed to determine if an HTTP response is "fresh" according to client-provided caching headers. Part of the `jshttp` organization, which maintains foundational HTTP middleware and utilities leveraged by frameworks such as Express.js, this library compares a client's `If-None-Match` and `If-Modified-Since` request headers against a server's `ETag` and `Last-Modified` response headers. It returns `true` if the cached response is still valid, indicating a conditional GET request can result in a 304 Not Modified status, or `false` if the cache is stale and a full response is required. Its primary differentiators are strict adherence to HTTP specifications and a focused scope, prioritizing reliability for efficient conditional GET implementations. Given its mature and foundational nature, the package maintains a stable, maintenance-level release cadence with infrequent updates.
Common errors
-
TypeError: fresh is not a function
cause Attempting to import the `fresh` function as a named import (e.g., `import { fresh } from 'fresh'`) or trying to access it as a property on the `require`d object (e.g., `require('fresh').fresh`) when it is exported as a default/module.exports.fixUse a default import for ESM (`import fresh from 'fresh'`) or directly assign the result of `require()` for CommonJS (`const fresh = require('fresh')`). -
Resource incorrectly reported as fresh/stale due to header casing or format.
cause Although HTTP headers are case-insensitive, JavaScript object keys are case-sensitive. If the header keys provided to `fresh` (e.g., `If-None-Match`) do not match the expected internal parsing or are in an unexpected format, the freshness check may yield incorrect results.fixEnsure request and response header keys are consistently lowercase or normalized before passing them to `fresh`, or rely on the module's internal parsing to handle standard HTTP header casing. Always provide full HTTP-standard header strings (e.g., `Last-Modified` in RFC1123 format).
Warnings
- gotcha The `fresh` module is designed to strictly follow HTTP specifications and does not implement workarounds for client-side browser bugs. Notably, certain versions of Safari have a known issue where they might incorrectly make a request that allows `fresh` to validate resource freshness even when Safari does not possess a representation of the resource in its cache. For Express applications, the `jumanji` module is suggested as a workaround for this specific Safari bug.
- gotcha The `fresh` package, being published in 2017, is fundamentally a CommonJS module. While modern build tools and Node.js environments often provide interoperability for `import fresh from 'fresh'`, direct usage in native ESM environments requiring strict ESM imports might necessitate `createRequire` or other compatibility layers for older CJS-only packages.
Install
-
npm install fresh -
yarn add fresh -
pnpm add fresh
Imports
- fresh
import { fresh } from 'fresh'import fresh from 'fresh'
- fresh
const fresh = require('fresh').freshconst fresh = require('fresh')
Quickstart
import fresh from 'fresh';
// Simulate a client request with caching headers
const requestHeaders = {
'if-none-match': '"my-etag-v1"',
'if-modified-since': new Date(Date.now() - 3600000).toUTCString() // 1 hour ago
};
// Simulate server response headers for a resource
const responseHeadersFresh = {
'etag': '"my-etag-v1"',
'last-modified': new Date().toUTCString()
};
const responseHeadersStale = {
'etag': '"my-etag-v2"',
'last-modified': new Date(Date.now() - 7200000).toUTCString() // 2 hours ago
};
// Check freshness against a fresh resource
const isFresh1 = fresh(requestHeaders, responseHeadersFresh);
console.log(`Is resource 1 fresh? ${isFresh1}`); // Expected: true
// Check freshness against a stale resource (different ETag)
const isFresh2 = fresh(requestHeaders, responseHeadersStale);
console.log(`Is resource 2 fresh? ${isFresh2}`); // Expected: false
// Simulate Cache-Control: no-cache from client
const requestHeadersNoCache = { ...requestHeaders, 'cache-control': 'no-cache' };
const isFreshNoCache = fresh(requestHeadersNoCache, responseHeadersFresh);
console.log(`Is resource fresh with no-cache? ${isFreshNoCache}`); // Expected: false (client forces revalidation)