Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
CachePolicy
✓ import { CachePolicy } from 'http-cache-semantics';
✗ const CachePolicy = require('http-cache-semantics').CachePolicy;
Main class for evaluating HTTP cache policy. The library ships with TypeScript types and supports both ESM and CommonJS.
CachePolicyOptions
✓ import type { CachePolicyOptions } from 'http-cache-semantics';
TypeScript type for the constructor options of CachePolicy, useful for type-checking.
CachePolicy
✓ import { CachePolicy } from 'http-cache-semantics';
✗ import CachePolicy from 'http-cache-semantics';
CachePolicy is a named export, not a default export. Incorrectly using a default import will result in a TypeError.
Demonstrates the basic workflow of `http-cache-semantics`: creating a `CachePolicy` from an initial request/response, checking its storability, caching it, and then using `satisfiesWithoutRevalidation()` to determine if a subsequent request can be served from the cache, respecting `Vary` headers and other HTTP rules.
import { CachePolicy } from 'http-cache-semantics';
// Simulate an initial request and its corresponding response
const initialRequest = {
url: 'https://api.example.com/data/items',
method: 'GET',
headers: {
'accept': 'application/json',
'authorization': 'Bearer mysecrettoken'
},
};
const initialResponse = {
status: 200,
headers: {
'cache-control': 'public, max-age=3600, s-maxage=600',
'content-type': 'application/json',
'vary': 'Accept, Authorization', // Note: Library expects lowercase, but here we simulate a common server response
'date': new Date().toUTCString(),
},
body: '{"id": 1, "name": "Cached Item"}',
};
// Options for the cache policy evaluation
const options = {
shared: true, // Evaluate from a shared cache perspective (e.g., a proxy)
cacheHeuristic: 0.1, // 10% of response's age as fallback TTL
immutableMinTimeToLive: 24 * 3600 * 1000, // 24 hours for 'immutable'
};
// --- Step 1: Create and store the cache policy for an incoming response ---
// Ensure headers are lowercase before passing to CachePolicy
const lowercaseInitialRequest = { ...initialRequest, headers: Object.fromEntries(Object.entries(initialRequest.headers).map(([k, v]) => [k.toLowerCase(), v])) };
const lowercaseInitialResponse = { ...initialResponse, headers: Object.fromEntries(Object.entries(initialResponse.headers).map(([k, v]) => [k.toLowerCase(), v])) };
const policy = new CachePolicy(lowercaseInitialRequest, lowercaseInitialResponse, options);
if (!policy.storable()) {
console.log("Initial response is not storable in the cache. Discarding.");
} else {
const letsPretendThisIsSomeCache = new Map<string, { policy: CachePolicy, body: string }>();
const timeToLive = policy.timeToLive();
console.log(`Response is storable. Estimated time to live: ${timeToLive}ms`);
// Store the policy object along with the response body
letsPretendThisIsSomeCache.set(initialRequest.url, { policy, body: initialResponse.body });
// --- Step 2: Later, an identical new request comes in ---
const newRequest = {
url: 'https://api.example.com/data/items',
method: 'GET',
headers: {
'accept': 'application/json',
'authorization': 'Bearer mysecrettoken'
},
};
const cachedEntry = letsPretendThisIsSomeCache.get(newRequest.url);
if (cachedEntry) {
// Ensure headers are lowercase for the new request too
const lowercaseNewRequest = { ...newRequest, headers: Object.fromEntries(Object.entries(newRequest.headers).map(([k, v]) => [k.toLowerCase(), v])) };
if (cachedEntry.policy.satisfiesWithoutRevalidation(lowercaseNewRequest)) {
// The cached response is valid for the new request without revalidation
const responseHeaders = cachedEntry.policy.responseHeaders();
console.log("Cached response can be used without revalidation.");
console.log("Updated response headers for client (includes Age, removes private headers):", responseHeaders);
// In a real application, you would send { headers: responseHeaders, body: cachedEntry.body } to the client.
} else {
console.log("Cache hit, but revalidation is required or response is not suitable for this new request.");
// Implement revalidation logic using policy.revalidationHeaders() and policy.revalidatedPolicy()
}
} else {
console.log("Cache miss. No entry found for this URL.");
// Fetch fresh data
}
}
Errors
Common errors & fixes
TypeError: Cannot read properties of undefined (reading 'headers')
The `request` or `response` object passed to the `CachePolicy` constructor is missing the `headers` property, or it is `null`/`undefined`.
fixEnsure both `request` and `response` objects always include a `headers` property, even if it's an empty object (`{}`), before being used to instantiate `CachePolicy`. Cached response not served, even though 'Cache-Control: max-age' indicates it should be fresh.
The cached response has a `Vary` header, and the headers of the new request do not match those of the original request used to create the cache entry, or the new request contains restrictive cache control directives (e.g., `Cache-Control: no-cache`).
fixAlways use `policy.satisfiesWithoutRevalidation(newRequest)` to check if a cached response can be validly served for a new request. This method correctly evaluates `Vary` headers and other request-specific conditions, which simple freshness checks like `timeToLive()` do not.
Incorrect caching of `private` or `s-maxage` responses in a shared/single-user context.
The `shared` option in the `CachePolicy` constructor is not correctly configured for the caching environment (e.g., `shared: false` for a proxy, or `shared: true` for a single-user cache leading to private data exposure).
fixSet `options.shared: true` (the default) for shared caches (e.g., HTTP proxies) to respect `s-maxage` and treat `private` as non-cacheable. Set `options.shared: false` for single-user caches (e.g., browser-like caches) to ignore `s-maxage` and allow caching of `private` responses.
Audit
Dependencies
No dependency data recorded yet.