@web-widget/shared-cache
Version:
Standards-compliant HTTP cache implementation for server-side JavaScript with RFC 7234 compliance and cross-runtime support
215 lines (160 loc) • 12.1 kB
Markdown
# SharedCache
[](https://github.com/web-widget/shared-cache/actions/workflows/test.yml?query=event%3Apush)
[](https://www.npmjs.com/package/@web-widget/shared-cache)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
[](https://codecov.io/gh/web-widget/shared-cache)
[](https://nodejs.org/)
[](https://deno.land/)
[](https://bun.sh/)
[](https://wintercg.org/)
[](https://tools.ietf.org/html/rfc7234)
A standards-compliant HTTP cache implementation for server-side applications.
SharedCache is an HTTP caching library that follows Web Standards and HTTP specifications. It implements a cache interface similar to the [Web Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache) but optimized for server-side shared caching scenarios.
## 📋 Table of Contents
- [✨ Key Features](#-key-features)
- [🤔 Why SharedCache?](#-why-sharedcache)
- [⚡ Quick Decision Guide](#-quick-decision-guide)
- [📦 Installation](#-installation)
- [🚀 Quick Start](#-quick-start)
- [📋 Standards Compliance](#-standards-compliance)
- [☁️ Cloudflare Comparison](#️-cloudflare-comparison)
- [📖 Documentation](#-documentation)
- [🤝 Who's Using SharedCache](#-whos-using-sharedcache)
- [🙏 Acknowledgments](#-acknowledgments)
- [📄 License](#-license)
## ✨ Key Features
- 📋 **RFC Compliance**: Supports [RFC 5861](https://tools.ietf.org/html/rfc5861) directives like `stale-if-error` and `stale-while-revalidate`
- 🎯 **Smart Caching**: Handles complex HTTP scenarios including `Vary` headers, proxy revalidation, and authenticated responses
- 🔧 **Flexible Storage**: Pluggable storage backend supporting memory, Redis, or any custom key-value store
- 🚀 **Enhanced Fetch**: Extends the standard `fetch` API with caching capabilities while maintaining full compatibility
- 🔌 **Middleware Origin**: `createCacheHandler` for in-process handlers (e.g. middleware `next()`)
- 🎛️ **Custom Cache Keys**: Cache key customization supporting device types, cookies, headers, and URL components
- ⚡ **Shared Cache Optimization**: Prioritizes `s-maxage` over `max-age` for shared cache performance
- 🌍 **Universal Runtime**: Compatible with [WinterCG](https://wintercg.org/) environments including Node.js, Deno, Bun, and Edge Runtime
## 🤔 Why SharedCache?
While the Web `fetch` API has become ubiquitous in server-side JavaScript, existing browser Cache APIs are designed for single-user scenarios. Server-side applications need shared caches that serve multiple users efficiently.
SharedCache provides:
- **Server-Optimized Caching**: Designed for multi-user server environments
- **Standards Compliance**: Follows HTTP specifications and server-specific patterns
- **Production Ready**: Battle-tested patterns from CDN and proxy implementations
## ⚡ Quick Decision Guide
### ✅ Use SharedCache When:
- **Node.js environments** - Native `caches` API not available
- **API response caching** - Need to reduce backend load and improve response times
- **Cross-runtime portability** - Want consistent caching across Node.js, Deno, Bun
- **Custom storage backends** - Need Redis, database, or distributed caching solutions
- **Meta-framework development** - Building applications that deploy to multiple environments
### ❌ Don't Use SharedCache When:
- **Edge runtimes with native caches** - Cloudflare Workers, Vercel Edge already provide `caches` API
- **Browser applications** - Use the native Web Cache API instead (unless you need HTTP cache control directives support)
- **Simple in-memory caching** - Consider lighter alternatives like `lru-cache` directly
- **Single-request caching** - Basic memoization might be sufficient
## 📦 Installation
```bash
npm install @web-widget/shared-cache
```
```bash
# Using yarn
yarn add @web-widget/shared-cache
# Using pnpm
pnpm add @web-widget/shared-cache
```
## 🚀 Quick Start
```typescript
import {
CacheStorage,
createFetch,
type KVStorage,
} from '@web-widget/shared-cache';
import { LRUCache } from 'lru-cache';
const createLRUCache = (): KVStorage => {
const store = new LRUCache<string, any>({ max: 1024 });
return {
async get(cacheKey: string) {
return store.get(cacheKey);
},
async set(cacheKey: string, value: any, ttl?: number) {
store.set(cacheKey, value, { ttl });
},
async delete(cacheKey: string) {
return store.delete(cacheKey);
},
};
};
const caches = new CacheStorage(createLRUCache());
async function example() {
const cache = await caches.open('api-cache-v1');
const fetch = createFetch(cache, {
defaults: {
cacheControlOverride: 's-maxage=300',
ignoreRequestCacheControl: true,
},
});
const response1 = await fetch(
'https://httpbin.org/response-headers?cache-control=max-age%3D604800'
); // First request: network
const response2 = await fetch(
'https://httpbin.org/response-headers?cache-control=max-age%3D604800'
); // Second request: cache
console.log(response2.headers.get('x-cache-status')); // "HIT"
}
example();
```
### Core APIs
| Export | Purpose |
| ------------------------ | ------------------------------------ |
| `createFetch` | Outbound HTTP fetch with caching |
| `createCacheHandler` | In-process origin (middleware / SSR) |
| `CacheStorage` / `Cache` | Cache storage and operations |
| `KVStorage` | Pluggable storage backend interface |
Every response includes an `x-cache-status` header (`HIT`, `MISS`, `UPDATING`, `STALE`, …) for debugging. See the [configuration guide](docs/configuration.md#cache-status-monitoring) for the full status table.
## 📋 Standards Compliance
SharedCache is built for production HTTP caching with full adherence to web standards:
| Standard | Status | Coverage |
| ----------------------------------------------------------------------- | ------------------ | --------------------------------------- |
| [RFC 7234](https://tools.ietf.org/html/rfc7234) (HTTP Caching) | ✅ Fully Compliant | 100% |
| [RFC 5861](https://tools.ietf.org/html/rfc5861) (`stale-*` extensions) | ✅ Fully Compliant | 100% |
| [Web Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache) | ✅ Subset | Core methods (`match`, `put`, `delete`) |
| [WinterCG](https://wintercg.org/) | ✅ Fully Supported | 100% |
**Highlights:**
- **RFC 7234**: Cache-Control directives, GET/HEAD caching, Vary processing, conditional requests
- **RFC 5861**: `stale-while-revalidate` and `stale-if-error` via `createFetch`
- **Web Cache API**: Core methods with HTTP semantics; `match()` / `delete()` support `ignoreMethod` (same subset as [Cloudflare Workers Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/))
- **Security**: Requests with `Authorization` headers are not cached unless the response explicitly allows it (`public`, `s-maxage`, etc.)
Powered by [`http-cache-semantics`](https://github.com/web-widget/http-cache-semantics) for RFC-compliant cache policy evaluation.
**[→ Full standards compliance guide](docs/standards-compliance.md)** — Web Cache API details, security notes, and implementation status.
## ☁️ Cloudflare Comparison
SharedCache is designed for **origin-side caching** (application servers with pluggable `KVStorage` such as Redis or S3), not as a replacement for Cloudflare's global edge cache. Where it helps to align with Cloudflare semantics, the library mirrors familiar patterns from the CDN and [Workers Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/):
- **Cache Key** — public `cacheKeyRules` (`search`, `header`, `cookie`, `device`) vs [Cloudflare Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-keys/)
- **Cache Status** — `x-cache-status` (`HIT`, `MISS`, `UPDATING`, `STALE`, …) vs `CF-Cache-Status`
- **Workers Cache API** — `match()` / `delete()` with `ignoreMethod` only; no `ignoreSearch` / `ignoreVary`
- **Storage** — `KVStorage` at the origin vs platform-managed edge / Workers cache
**[→ Full comparison guide](docs/cloudflare-cache-comparison.md)** — quick reference table and detailed notes.
## 📖 Documentation
| Guide | Description |
| ------------------------------------------------------------ | -------------------------------------------------------------------- |
| [Examples](docs/examples.md) | Redis, multi-tenant, authentication, and custom storage patterns |
| [Configuration](docs/configuration.md) | Global setup, `sharedCache` options, cache key rules, and monitoring |
| [API Reference](docs/api-reference.md) | Complete API signatures and type definitions |
| [Logging](docs/logging.md) | Logger setup, log levels, and debugging techniques |
| [FAQ](docs/faq.md) | Storage backends, edge runtimes, Vary performance, and more |
| [Standards Compliance](docs/standards-compliance.md) | RFC details, Web Cache API subset, and security notes |
| [Cloudflare Comparison](docs/cloudflare-cache-comparison.md) | Mapping to Cloudflare Cache Rules and Workers Cache API |
## 🤝 Who's Using SharedCache
- [Web Widget Meta Framework: Cache middleware](https://github.com/web-widget/web-widget/blob/main/packages/middlewares/src/cache.ts)
- [InsMind.com: Page Cache](https://www.insmind.com/)
- [Gaoding.com: Page Cache (Million-level URLs)](https://www.gaoding.com/)
## 🙏 Acknowledgments
SharedCache draws inspiration from industry-leading caching implementations:
- **[Cloudflare Cache Key](https://developers.cloudflare.com/cache/how-to/cache-keys/)** - Cache key customization patterns
- **[Next.js Data Cache](https://nextjs.org/docs/app/building-your-application/caching#data-cache)** - Server-side caching strategies
- **[nodejs/undici](https://github.com/nodejs/undici/blob/main/lib/web/cache/cache.js)** - Web Standards implementation
- **[http-cache-lru](https://github.com/o-development/http-cache-lru/)** - HTTP cache semantics
- **[Cloudflare Miniflare](https://github.com/cloudflare/miniflare/blob/master/packages/cache/src/cache.ts)** - Edge runtime patterns
- **[Cloudflare Workers SDK](https://github.com/cloudflare/workers-sdk/blob/main/packages/miniflare/src/workers/cache/cache.worker.ts)** - Worker environment optimizations
- **[ultrafetch](https://github.com/natemoo-re/ultrafetch)** - Fetch API extensions
- **[island.is Cache Middleware](https://github.com/island-is/island.is/blob/main/libs/clients/middlewares/src/lib/withCache/withCache.ts)** - Production caching patterns
- **[make-fetch-happen](https://github.com/npm/make-fetch-happen)** - HTTP caching with retry and offline support
## 📄 License
MIT License - see [LICENSE](LICENSE) file for details.