axios-cache-interceptor

Cache interceptor for Axios that adds RFC 7234-aware HTTP caching, deduplication, and pluggable storage with one setupCache() call.

Library
npm
v1.12.3
818stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
76/100Good
Development Activity76
Maintenance80
Community52
Maturity56
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture85
Code Quality90
Innovation75
Learning Curve75

axios-cache-interceptor wraps an existing Axios instance with a request/response interceptor pair that implements HTTP caching semantics for GET and HEAD requests by default. It reads standard Cache-Control, Expires, ETag, and Last-Modified headers to determine freshness, transparently deduplicates concurrent requests for the same resource key, and revalidates stale entries using conditional requests instead of re-fetching wholesale.

The library ships with in-memory and Web Storage adapters out of the box, and exposes a buildStorage() helper so applications can plug in Redis, IndexedDB, or any other backing store while keeping the same interceptor logic. Its per-request cache config, Vary-aware key generation, and stale-if-error fallback make it a drop-in caching layer for API clients that need to reduce network waste without hand-rolling cache logic.

What You Get

  • Drop-in setupCache() wrapper that adds caching to any existing Axios instance with no call-site changes
  • Built-in memory and Web Storage (localStorage/sessionStorage) storage adapters, plus a buildStorage() helper for custom backends like Redis or IndexedDB
  • RFC 7234-aware header interpretation (Cache-Control, Expires, ETag, Last-Modified) with configurable per-request overrides
  • Automatic in-flight request deduplication so concurrent calls to the same endpoint share one network request
  • Vary-header-aware cache keys that avoid serving mismatched cached variants across differing request headers
  • Stale-if-error fallback that serves the last known-good cached response when revalidation fails

Common Use Cases

  • Reducing redundant API calls in SPAs/dashboards that repeatedly request the same reference or list data
  • Adding ETag/Last-Modified conditional revalidation to a backend service client without writing custom cache logic
  • Deduplicating bursts of concurrent requests for the same resource during page load or rapid re-renders
  • Persisting cache entries across page reloads in browser apps via the Web Storage adapter
  • Swapping in a shared Redis-backed storage for cache reuse across serverless function invocations or multiple server instances

Under The Hood

Architecture setupCache() (src/cache/create.ts) attaches defaultRequestInterceptor (src/interceptors/request.ts) and defaultResponseInterceptor (src/interceptors/response.ts) onto the Axios instance’s existing interceptor chain, storing shared state (storage, waiting map, generateKey, headerInterpreter) directly on the Axios object cast as AxiosCacheInstance. The request interceptor computes a cache key via defaultKeyGenerator (src/util/key-generator.ts), consults axios.storage.get() (built via buildMemoryStorage or buildWebStorage, both implementing the buildStorage() contract in src/storage/build.ts), and either short-circuits to a synthetic cached adapter or lets the request proceed while registering a deferred in axios.waiting to deduplicate concurrent callers. The core abstraction all logic branches on is a StorageValue state machine (empty/loading/cached/stale/must-revalidate), so the design is a thin, stateful middleware layer around Axios’s own interceptor pipeline rather than a replacement HTTP client.

Tech Stack TypeScript with axios ^1.19.0 as a peer dependency, and a handful of small helper packages authored by the same maintainer for parsing and comparison: cache-parser (Cache-Control parsing), fast-defer (deferred promises), http-vary (Vary header parsing/comparison), object-code (key hashing), and try (safe error wrapping). Builds run through tsdown, producing ESM/CJS/UMD bundles plus a separate development-mode entry point. Linting and formatting use Biome, docs are built with VitePress, and tests run on Node’s built-in test runner with c8 coverage reporting.

Code Quality An extensive test suite under test/ covers interceptors (etag, vary, abort-request, concurrent-error, stale-if-error, hydrate, last-modified, waiting-memory-leak), storage adapters (memory, web, quota), header parsing (cache-control, expires, interpreter), and utilities (cache-predicate, key-generator, update-cache), run via Node’s test runner with c8 coverage reporting. The codebase uses strict TypeScript throughout with exported types for every public surface, Biome for consistent linting/formatting enforced in CI, and a dedicated type-check step. Error handling is deliberate rather than swallowed: the request interceptor explicitly rethrows and propagates deferred rejections to every waiting caller, with inline comments justifying each branch of its state machine.

API Design The public surface is intentionally minimal: a single setupCache(axios, options) call attaches caching to an existing instance and returns it with extended types, so existing axios.get()/request() call sites need no changes. Storage adapters, key generation, and header interpretation are all swappable through plain options objects rather than subclassing, and per-request overrides reuse the same cache option shape as the global config, keeping the API surface consistent between global and per-call configuration. Documentation is thorough, with dedicated guides for getting started, debugging, storages, and per-request specifics, plus a generated llms-full.txt for AI assistants.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search