express-memorize - v1.2.0
    Preparing search index...

    express-memorize - v1.2.0

    express-memorize

    npm version npm downloads CI license TypeScript

    In-memory cache middleware for Express.js.
    Caches GET responses with optional TTL — zero dependencies, fully typed.


    • Caches GET responses automatically when status code is 2xx
    • Per-route TTL override
    • Event hooks: set, delete, expire
    • Cache inspection and invalidation API
    • X-Cache: HIT | MISS response header
    • Zero runtime dependencies
    • Full TypeScript support
    npm install express-memorize
    
    import express from 'express';
    import { memorize } from 'express-memorize';

    const app = express();
    const cache = memorize({ ttl: 30_000 }); // 30 seconds global TTL

    app.get('/users', cache(), async (req, res) => {
    const users = await db.getUsers();
    res.json({ data: users });
    });

    app.listen(3000);

    The first request computes the response normally. Every subsequent GET /users is served from memory until the TTL expires.

    Apply the cache to the entire application with app.use(). Every GET route is cached automatically — non-GET requests are bypassed without any extra configuration.

    const cache = memorize({ ttl: 60_000 });

    app.use(cache()); // applies to all GET routes

    app.get('/users', (req, res) => { res.json({ data: users }) });
    app.get('/products', (req, res) => { res.json({ data: products }) });
    // POST, PUT, PATCH, DELETE routes are unaffected
    const cache = memorize({ ttl: 60_000 });

    app.get('/products', cache(), (req, res) => {
    res.json({ data: products });
    });
    const cache = memorize({ ttl: 60_000 }); // global: 60s

    app.get('/users', cache(), handler); // 60s
    app.get('/products', cache({ ttl: 10_000 }), handler); // override: 10s
    app.get('/config', cache({ ttl: 0 }), handler); // no expiry
    const cache = memorize({ ttl: 30_000 });

    app.get('/users', cache(), (req, res) => {
    res.json({ data: users });
    });

    app.post('/users', (req, res) => {
    users.push(req.body);
    cache.delete('/users'); // invalidate after mutation
    res.status(201).json({ data: req.body });
    });
    const cache = memorize({ ttl: 30_000 });

    cache.on('set', (e) => {
    console.log(`[cache] stored ${e.key} — expires in ${e.expiresAt ? e.expiresAt - Date.now() : '∞'}ms`);
    });

    cache.on('delete', (e) => {
    console.log(`[cache] deleted ${e.key}`);
    });

    cache.on('expire', (e) => {
    console.log(`[cache] expired ${e.key}`);
    });
    cache.get('/users');   // CacheInfo | null — single entry
    cache.getAll(); // Record<string, CacheInfo> — all active entries

    CacheInfo shape:

    {
    key: string;
    body: unknown;
    statusCode: number;
    contentType: string;
    expiresAt: number | null;
    remainingTtl: number | null; // ms until expiry, null if no TTL
    }
    cache.delete('/users');  // remove one entry
    cache.clear(); // remove all entries

    Creates a cache instance. Returns a Memorize object.

    Option Type Default Description
    ttl number undefined Time-to-live in milliseconds. Omit for no expiry.

    Returns an Express RequestHandler middleware. Can override the global TTL.

    Option Type Default Description
    ttl number global ttl TTL override for this specific route.
    Method Signature Description
    get (key: string) => CacheInfo | null Returns info for a cached key.
    getAll () => Record<string, CacheInfo> Returns all active cache entries.
    delete (key: string) => boolean Removes a single entry. Returns false if not found.
    clear () => void Removes all entries.
    Event Payload When
    set { type, key, body, statusCode, contentType, expiresAt } A response is stored
    delete { type, key } cache.delete() or cache.clear() is called
    expire { type, key } TTL timer fires or lazy expiry is detected
    Header Value Description
    X-Cache HIT Response served from cache
    X-Cache MISS Response computed and stored
    • Only GET requests are cached. All other methods bypass the middleware entirely.
    • Only responses with a 2xx status code are stored.
    • Each call to cache() returns an independent middleware handler, but all handlers created from the same memorize() instance share the same store.
    • Two separate memorize() calls produce independent stores.

    MIT