TypeScript icon, indicating that this package has built-in type declarations

2.2.14 • Public • Published


npm version npm downloads Mastodon Follow

[!NOTE] This is one of 192 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.

🚀 Please help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️


In-memory cache implementations with different eviction strategies.

Available strategies

  • LRU: Least Recently Used
  • TLRU: Time-aware Least Recently Used
  • MRU: Most Recently Used


  • ES6 Map-like API (with minor differences)
  • Supports any types for both keys & values
  • Customizable cache limits (no. of items / actual size)
  • Customizable key equality checks (@thi.ng/equiv by default)
  • Optional item update & release callbacks (e.g. to clean up resources when value is being updated or evicted)


STABLE - used in production

Search or submit any issues for this package

Related packages

  • @thi.ng/associative - Alternative Map and Set implementations with customizable equality semantics & supporting operations, plain object utilities


yarn add @thi.ng/cache

ESM import:

import * as cache from "@thi.ng/cache";

Browser ESM import:

<script type="module" src="https://esm.run/@thi.ng/cache"></script>

JSDelivr documentation

For Node.js REPL:

const cache = await import("@thi.ng/cache");

Package sizes (brotli'd, pre-treeshake): ESM: 1.06 KB


Usage examples

One project in this repo's /examples directory is using this package:

Screenshot Description Live demo Source
Filterable commit log UI w/ minimal server to provide commit history Demo Source


Generated API docs

Common config options

All caches support at least the following options (all optional):

interface CacheOpts<K, V> {
     * Key size calculation
    ksize: (k: K) => number;
     * Value size calculation
    vsize: (v: V) => number;
     * Eviction callback to clean up resources
    release: (k: K, v: V) => void;
     * Update callback to clean up resources
    update: (k: K, vold: V, vnew: V) => void;
     * Factory for ES6 Map compatible instance
     * to index cache entries
    map: () => Map<K, any>;
     * Max number of items in cache (default: ∞)
    maxlen: number;
     * Max cache size (computed via `ksize` & `vsize`) (default: ∞)
    maxsize: number;


Removes least recently used items if a new item is added, but would not satisfy cache limit. Every time a cached item is accessed, it's recency is updated.

import { LRUCache } from "@thi.ng/cache";

// caches can be configured with maxlen, maxsize and sizing functions (see below)
const lru = new LRUCache<string, number>(null, { maxlen: 3 });
lru.set("foo", 23);
lru.set("bar", 42);
lru.set("baz", 66);

// true
// retrieving a value from the cache updates its timestamp
// 23

// caches are fully iterable
// largely intended for inspection only, does not update recency
// btw. "foo" appears last since most recently accessed
// [ { k: 'bar', v: 42, s: 0 },
//   { k: 'baz', v: 66, s: 0 },
//   { k: 'foo', v: 23, s: 0 } ]
// [ 'bar', 'baz', 'foo' ]
// [ 42, 66, 23 ]

// remove from cache
// true

// caches have a getSet() method to obtain & store a new value
// if its key is not known. this process is asynchronous
lru.getSet("boo", async () => 999).then(console.log);
// 999

// the given retrieval fn is only called if there's a cache miss
// (not the case here). `getSet()` always returns a promise
lru.getSet("boo", async () => 123).then(console.log);
// 999

// caches can be limited by size instead of (or in addition to)
// number of items. the meaning of `size` is user-defined.
// sizing fns can be provided for both keys & values (both default to 0)
// here we multiply value size by 8 since JS numbers are doubles by default
// we also provide a release hook for demo purposes

// the first arg is an iterable of KV pairs to store (just as for Map)
lru = new LRUCache<string, number[]>(
    [ ["a", [1.0, 2.0]], ["b", [3.0, 4.0, 5.0]] ],
        maxsize: 32,
        ksize: (k) => k.length,
        vsize: (v) => v.length * 8,
        release: (k, v) => console.log("release", k, v),
        update: (k, vold, vnew) => console.log("update", k, vold, "->", vnew)
// release a [1, 2] ("a" is evicted due to maxsize constraint)
// 25

// [ 'b' ]


Time-aware LRU cache. Extends LRU strategy with TTL (time-to-live) values associated with each entry. has() will only return true and get() only returns a cached value if its TTL hasn't yet expired. When adding a new value to the cache, first removes expired entries and if there's still not sufficient space removes entries in LRU order. set() takes an optional entry specific ttl arg. If not given, uses the cache instance's default (provided via ctor option arg). If no instance TTL is given, TTL defaults to 1 hour.

import { TLRUCache } from "@thi.ng/cache";

// same opts as LRUCache, but here with custom default TTL period (in ms)
tlru = new TLRUCache(null, { ttl: 10000 });

// with item specific TTL (500ms)
tlru.set("foo", 42, 500)


Similar to LRU, but removes most recently accessed items first. Wikipedia

import { MRUCache } from "@thi.ng/cache";

// same opts as LRUCache
mru = new MRUCache();


If this project contributes to an academic publication, please cite it as:

  title = "@thi.ng/cache",
  author = "Karsten Schmidt",
  note = "https://thi.ng/cache",
  year = 2018


© 2018 - 2024 Karsten Schmidt // Apache License 2.0

Package Sidebar


npm i @thi.ng/cache

Weekly Downloads






Unpacked Size

44.6 kB

Total Files


Last publish


  • thi.ng