LRU Memoization Utility
`lru-memoize` is a utility library for JavaScript and TypeScript that provides simple memoization for pure functions using an LRU (Least Recently Used) cache. It helps optimize performance by storing results of expensive function calls and returning the cached result when the same inputs occur again. The current stable version is 1.1.0, released recently with bug fixes and explicit TypeScript/Flow support. The package features a configurable cache limit, custom equality comparison functions, and an option for deep object comparison for arguments, making it flexible for various use cases. Its primary differentiation lies in its minimalist approach to LRU caching for functions, focusing on purity and avoiding side effects. The release cadence appears to be driven by bug fixes and improvements rather than frequent new features, ensuring stability over rapid, breaking changes.
Common errors
-
Function is always re-calculating, not using cache, even when called with object arguments that look identical.
cause By default, `lru-memoize` uses strict equality (`===`) for argument comparison. Since distinct object instances (even with identical properties) are not strictly equal, they are treated as unique cache keys.fixEnable deep object comparison by initializing `memoize` with `deepObjects: true`: `memoizedFunc = memoize(cacheLimit, null, true)(originalFunc);`. Alternatively, provide a custom `equals` function for specific comparison needs. -
TypeError: memoizedFunction is not a function (or similar import errors like 'memoize is not defined')
cause This error typically indicates an incorrect import statement, particularly when mixing ESM `import` syntax with CommonJS `require` expectations, or attempting a named import where a default import is required.fixFor ES Modules (e.g., in a modern React/Vue project): `import memoize from 'lru-memoize';`. For CommonJS (e.g., in a Node.js script): `const memoize = require('lru-memoize');`. -
The memoized function only caches the most recent result; previous results are always re-calculated when recalled.
cause The default cache `limit` for `lru-memoize` is `1`. This means that only the absolute last unique set of arguments and its computed result are retained in the cache. Any new unique call will replace the single cached entry.fixIncrease the cache limit when initializing `memoize` to accommodate more entries. For example, to cache 10 unique results, use: `memoizedFunc = memoize(10)(originalFunc);`.
Warnings
- gotcha `lru-memoize` is designed exclusively for pure functions. Memoizing functions that have side effects (e.g., modifying external state, performing network requests) or rely on external mutable state will lead to incorrect or stale results, as the function will not re-execute when its external dependencies change.
- gotcha By default, `lru-memoize` uses strict equality (`===`) to compare function arguments. If your memoized function receives object or array arguments that might be different instances but contain identical data, they will be treated as distinct cache keys, leading to cache misses.
- gotcha The `limit` parameter for the LRU cache defaults to `1`. This means that by default, `lru-memoize` will only store the result of the very last unique set of arguments. Any call with different arguments will evict the previous entry.
Install
-
npm install lru-memoize -
yarn add lru-memoize -
pnpm add lru-memoize
Imports
- memoize
import { memoize } from 'lru-memoize';import memoize from 'lru-memoize';
- memoize
const memoize = require('lru-memoize');
Quickstart
import memoize from 'lru-memoize';
// A "pure" function to be memoized. It calculates the product of three numbers.
// We add a console log to demonstrate when the actual calculation occurs.
const multiply = (a: number, b: number, c: number): number => {
console.log(`Calculating for ${a}, ${b}, ${c}...`); // Shows when the function actually runs
return a * b * c;
};
// Memoize the 'multiply' function with a cache limit of 2.
// This means it will remember the last 2 unique sets of arguments and their results.
const memoizedMultiply = memoize(2)(multiply);
console.log('--- Demonstrating Cache Hits and Evictions ---');
console.log('1. First call:', memoizedMultiply(2, 3, 4)); // Calculates: (24) -> cache: [(2,3,4):24]
console.log('2. Second call:', memoizedMultiply(5, 6, 7)); // Calculates: (210) -> cache: [(5,6,7):210, (2,3,4):24]
console.log('3. First call again (cached):', memoizedMultiply(2, 3, 4)); // Hits cache -> cache: [(2,3,4):24, (5,6,7):210]
console.log('4. New call (evicts oldest):', memoizedMultiply(1, 2, 3)); // Calculates: (6) -> cache: [(1,2,3):6, (2,3,4):24]
console.log('5. Second call again (cached):', memoizedMultiply(5, 6, 7)); // Calculates (was evicted) -> cache: [(5,6,7):210, (1,2,3):6]
console.log('6. First call again (evicted, re-calculates):', memoizedMultiply(2, 3, 4)); // Calculates -> cache: [(2,3,4):24, (5,6,7):210]