{"id":17104,"library":"http-cache-middleware","title":"HTTP Cache Middleware","description":"http-cache-middleware is a high-performance connect-like HTTP cache middleware designed for Node.js applications. It leverages the popular `cache-manager` package, providing flexibility to integrate various storage engines like in-memory, Redis, and more. The library significantly reduces latency by enabling robust caching strategies, capable of improving response times from tens of milliseconds down to single digits. It supports custom `x-cache-timeout` and `x-cache-expire` headers for fine-grained control over cache entry and invalidation using glob patterns. Additionally, it transparently handles standard HTTP `Cache-Control` and `ETag` headers to facilitate browser-side caching and validation. The current stable version is 1.4.1, with recent updates indicating an active maintenance and development cadence focused on fixes and dependency updates, with minor cumulative releases.","status":"active","version":"1.4.1","language":"javascript","source_language":"en","source_url":"https://github.com/jkyberneees/http-cache-middleware","tags":["javascript","http","cache","middleware"],"install":[{"cmd":"npm install http-cache-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add http-cache-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add http-cache-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core caching layer, providing extensibility for various storage engines (e.g., Memory, Redis).","package":"cache-manager"},{"reason":"Used for parsing human-readable time strings (e.g., '1 minute', '1 hour') for cache timeouts.","package":"ms"},{"reason":"Powers the pattern matching for cache invalidation using the `x-cache-expire` header.","package":"matcher"},{"reason":"Provides conditional execution logic for the middleware, fixed in v1.4.1 for proper integration.","package":"middleware-if-unless"}],"imports":[{"note":"The package exports a default function that, when called, returns the middleware instance. It's typically used as a default import in ESM or a direct require call in CJS.","wrong":"import { middleware } from 'http-cache-middleware'","symbol":"middleware","correct":"import createCacheMiddleware from 'http-cache-middleware'; const middleware = createCacheMiddleware();"},{"note":"When integrating with specific `cache-manager` stores, you'll import `caching` and `redisStore` (or other store implementations) directly from `cache-manager` and its respective store packages.","wrong":"import CacheManager from 'cache-manager'","symbol":"CacheManager","correct":"import { caching } from 'cache-manager'; const redisCache = caching({ store: redisStore, ... });"},{"note":"In CommonJS, the `require` call directly returns the factory function, which must then be invoked to get the middleware instance. Omitting the `()` will result in a function, not the middleware itself.","wrong":"const httpCacheMiddleware = require('http-cache-middleware')","symbol":"httpCacheMiddleware","correct":"const httpCacheMiddleware = require('http-cache-middleware')();"}],"quickstart":{"code":"import createCacheMiddleware from 'http-cache-middleware';\nimport restana from 'restana';\n\nconst middleware = createCacheMiddleware();\nconst service = restana();\n\nservice.use(middleware);\n\nservice.get('/cache-on-get', (req, res) => {\n  setTimeout(() => {\n    res.setHeader('x-cache-timeout', '1 minute');\n    res.send('this supposed to be a cacheable response, fetched at ' + new Date().toISOString());\n  }, 50);\n});\n\nservice.delete('/invalidate-cache', (req, res) => {\n  // Simulate a data change that requires cache invalidation\n  console.log('Invalidating cache for /cache-on-get');\n  res.setHeader('x-cache-expire', '*/cache-on-get');\n  res.send('Cache invalidated');\n});\n\nconst port = process.env.PORT || 3000;\nservice.start(port).then(() => {\n  console.log(`Server started on port ${port}`);\n  console.log(`Try: curl http://localhost:${port}/cache-on-get`);\n  console.log(`Then: curl http://localhost:${port}/invalidate-cache`);\n  console.log(`Then: curl http://localhost:${port}/cache-on-get again`);\n});\n","lang":"javascript","description":"This quickstart demonstrates how to initialize the HTTP cache middleware with `restana`, set a cache timeout for a GET endpoint, and invalidate it using a DELETE request with `x-cache-expire`."},"warnings":[{"fix":"Use supported units for `x-cache-timeout` (e.g., '1s', '1m', '1h') or provide a numerical value in seconds directly if using an alternative method for timeout.","message":"The `ms` package, used for parsing `x-cache-timeout` header values, does not support the 'millisecond' unit. Ensure you use supported units like 'second', 'minute', 'hour', etc.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Be aware that the first request to a resource will not contain the generated browser cache headers. These headers appear only once the response is stored in the internal `http-cache-middleware` cache and subsequently served from it.","message":"When using `x-cache-timeout` to automatically generate `Cache-Control` and `ETag` headers for browser caching, these generated headers will only be observable on subsequent requests *after* the initial response has been cached (i.e., on a cache hit).","severity":"gotcha","affected_versions":">=1.2.0"},{"fix":"Ensure your `x-cache-expire` patterns are correctly defined according to `matcher` package specifications. Review any existing invalidation logic that might have worked around the previous bug.","message":"Fixes were introduced in v1.3.8 for wildcard pattern support in `x-cache-expire` that were previously not working as described. If you relied on broken behavior or custom workarounds, this fix might change behavior.","severity":"breaking","affected_versions":">=1.3.8"},{"fix":"No direct fix needed, but be aware of this change if you have observed or relied on specific timing in cache write operations under heavy load. This is generally a stability improvement.","message":"Version 1.3.5 introduced ordered, two-step async cache writing to prevent timing issues under high concurrency. While a fix, systems relying on specific concurrent cache writing behaviors might observe changes.","severity":"breaking","affected_versions":">=1.3.5"},{"fix":"Update to `v1.3.10` or newer to prevent errors when calling `cache.del` (implicitly via `x-cache-expire`) with patterns that resolve to an empty set of keys.","message":"A critical bug in v1.3.10 fixed `redis store error when passing empty keys array` to `cache.del`. Older versions would throw an error if an empty array was passed for cache invalidation.","severity":"breaking","affected_versions":">=1.3.10"},{"fix":"Ensure you are on v1.4.1 or newer for reliable conditional middleware behavior using `iff` or `unless`.","message":"The integration of `iff` and `unless` utility functions was fixed in v1.4.1. Previous versions might have had inconsistent or incorrect conditional middleware execution.","severity":"breaking","affected_versions":">=1.4.1"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Upgrade `http-cache-middleware` to version 1.3.10 or newer. This version includes a fix that gracefully handles empty key arrays.","cause":"Older versions of the middleware (prior to v1.3.10) would throw an error if an `x-cache-expire` pattern resulted in an empty array of keys to be deleted from the Redis cache.","error":"Redis store error when passing empty keys array to cache.del"},{"fix":"Update `http-cache-middleware` to version 1.3.8 or newer. Ensure your patterns are valid according to the `matcher` package syntax (e.g., `*/users` to match all paths ending with `/users`).","cause":"Versions prior to 1.3.8 had a bug where wildcard pattern support for cache invalidation was not working correctly.","error":"Wildcard patterns in x-cache-expire are not invalidating expected entries"},{"fix":"Ensure you invoke the factory function: `const middleware = require('http-cache-middleware')();`","cause":"In CommonJS environments, the `require('http-cache-middleware')` call returns a factory function, which must then be invoked to get the actual middleware instance. Developers often forget to call this function.","error":"TypeError: middleware is not a function"}],"ecosystem":"npm","meta_description":null}