{"id":17464,"library":"route-cache","title":"Route-Cache","description":"route-cache is an Express.js middleware designed for efficient server-side caching of HTTP route responses. Its primary goal is to accelerate backend performance for frequently accessed routes, alleviate server load during periods of high demand, and mitigate issues like the 'thundering herd' phenomenon by serving pre-computed content for a defined period (TTL). The package is currently at version 0.7.0. Release cadence appears sporadic, with the last notable update being 0.6.1, which included status code caching. Key advantages of `route-cache` include broad support for various content types, proper handling of HTTP redirects, the ability to implement conditional caching logic per request, including dynamic cache key generation based on `req` and `res` objects, and seamless integration with gzip compression. It provides both an in-memory caching solution (leveraging `lru-cache` internally) and extensibility for distributed caching mechanisms through pluggable stores, such as `IoRedisStore` for Redis integration. This flexibility makes it suitable for both small-scale applications and larger, distributed systems requiring shared cache states.","status":"active","version":"0.7.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/bradoyler/route-cache","tags":["javascript","middleware","express","cache","http-caching"],"install":[{"cmd":"npm install route-cache","lang":"bash","label":"npm"},{"cmd":"yarn add route-cache","lang":"bash","label":"yarn"},{"cmd":"pnpm add route-cache","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used internally for the default in-memory cache store since v0.3.0.","package":"lru-cache","optional":false},{"reason":"Required for using the `IoRedisStore` for distributed caching.","package":"ioredis","optional":true}],"imports":[{"note":"This package is primarily CommonJS. While Node.js's CJS-ESM interop might allow the ESM import in some contexts, the documented and guaranteed-to-work method is CommonJS `require`.","wrong":"import routeCache from 'route-cache';","symbol":"routeCache","correct":"const routeCache = require('route-cache');"},{"note":"This is a method on the `routeCache` object, not a direct named export.","wrong":"import { cacheSeconds } from 'route-cache';","symbol":"cacheSeconds","correct":"app.get('/path', routeCache.cacheSeconds(ttl), ...);"},{"note":"This distributed cache store is a separate CommonJS module within the package.","wrong":"import IoRedisStore from 'route-cache/ioRedisStore';","symbol":"IoRedisStore","correct":"const IoRedisStore = require('route-cache/ioRedisStore');"}],"quickstart":{"code":"const express = require('express');\nconst routeCache = require('route-cache');\nconst app = express();\n\n// Cache a route for 20 seconds using the default cache key (req.originalUrl)\napp.get('/cached-index', routeCache.cacheSeconds(20), (req, res) => {\n  console.log('This message will only appear once every 20 seconds for /cached-index');\n  res.send('This response is cached!');\n});\n\n// Cache a route with a custom, dynamic key based on user authentication status\napp.get('/user-data/:id', routeCache.cacheSeconds(60, (req, res) => {\n  // Assuming res.locals.isAuthenticated indicates user login status\n  if (!res.locals.isAuthenticated) return false; // Do not cache for unauthenticated requests\n  return req.originalUrl + '|' + req.params.id + '|' + res.locals.userId;\n}), (req, res) => {\n  res.locals.isAuthenticated = Math.random() > 0.5; // Simulate auth status\n  res.locals.userId = res.locals.isAuthenticated ? 'user123' : 'guest';\n  console.log(`Serving user data for ${req.params.id}. Authenticated: ${res.locals.isAuthenticated}`);\n  res.send(`Data for user ${req.params.id}. (Auth: ${res.locals.isAuthenticated})`);\n});\n\n// Example of how to explicitly remove a cached route\napp.post('/clear-cache', (req, res) => {\n  const routeToClear = req.body.route || '/cached-index';\n  routeCache.removeCache(routeToClear);\n  res.send(`Cache for ${routeToClear} cleared.`);\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n  console.log(`Server listening on port ${PORT}`);\n  console.log('Try visiting /cached-index multiple times, and /user-data/1 and /user-data/2');\n});","lang":"javascript","description":"This quickstart demonstrates how to use `route-cache` with an Express application, showing basic route caching with a TTL, dynamic cache key generation based on request/response properties (including conditional caching), and manual cache invalidation."},"warnings":[{"fix":"Upgrade to v0.1.2 or newer. If you need to cache specific error responses, implement custom caching logic that explicitly overrides this behavior via a dynamic key function.","message":"Prior to v0.1.2, `route-cache` might cache HTTP responses with status codes >= 400 (e.g., error pages). From v0.1.2 onwards, it explicitly avoids caching these invalid responses, which changes caching behavior for applications relying on the previous, less desirable default.","severity":"breaking","affected_versions":"<0.1.2"},{"fix":"Review routes where status code caching might introduce unexpected behavior. If dynamic status codes are critical, consider conditional caching or dynamic keys that factor in status logic.","message":"Version v0.6.1 introduced status code caching. This means the HTTP status code itself will be part of the cached response. While this is generally an improvement, it could subtly alter behavior if previous versions were used where the status code was re-evaluated on subsequent requests to a cached body.","severity":"breaking","affected_versions":">=0.6.1"},{"fix":"Always define a custom cache key function (`routeCache.cacheSeconds(ttl, function(req, res){ ... })`) for routes serving personalized or highly dynamic content to ensure proper cache isolation. Return `false` from the function to prevent caching for specific requests.","message":"By default, `route-cache` uses `req.originalUrl` as the cache key. For applications with dynamic content based on user sessions, query parameters (that are not part of `originalUrl` if not configured), or other request-specific data, this default key might lead to incorrect or shared cached responses.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Stick to CommonJS `require()` for importing `route-cache` and its sub-modules to ensure compatibility, or verify ESM support in your specific Node.js version and project configuration.","message":"The package documentation primarily uses CommonJS `require` syntax. Directly using ES module `import` syntax might not work out-of-the-box in pure ESM environments without proper configuration (e.g., transpilation or specific Node.js loader setup) or if the package does not explicitly provide ESM exports.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Upgrade `route-cache` to version 0.4.7 or higher to resolve the underlying JSON null error.","cause":"An issue where JSON parsing failed if the response body was null, fixed in v0.4.7.","error":"TypeError: Cannot read properties of null (reading 'json')"},{"fix":"Either decrease the `ttl` (Time-To-Live) for `cacheSeconds`, or explicitly call `routeCache.removeCache('/your-route')` after data updates to invalidate the specific cached entry. For production, consider using distributed caching with invalidation hooks.","cause":"The route is being cached, and the cache has not expired or been explicitly cleared.","error":"Old content is being served even after data has changed."},{"fix":"Implement a custom cache key function for the affected route. The key should incorporate identifying information like `req.session.userId` or a unique user identifier, e.g., `routeCache.cacheSeconds(ttl, (req, res) => req.originalUrl + '|' + res.locals.userId);`.","cause":"The default cache key (`req.originalUrl`) does not differentiate between personalized content for different users.","error":"Responses for different users are getting mixed up in the cache."}],"ecosystem":"npm","meta_description":null}