{"id":12152,"library":"toad-cache","title":"Toad Cache: LRU and FIFO Caching","description":"Toad Cache is a JavaScript/TypeScript library offering in-memory Least-Recently-Used (LRU) and First-In-First-Out (FIFO) caching strategies suitable for both client-side (browser) and server-side (Node.js) environments. The current stable version is 3.7.0. Releases appear to be ad-hoc, driven by feature additions and bug fixes rather than a strict schedule. A key differentiator since version 3.0.0 is the direct export of `Lru` and `Fifo` classes, allowing direct instantiation with `new` rather than a factory function, providing a more idiomatic class-based API. It also supports optional cache statistics tracking (hit/miss/expiration) via the `LruHitStatistics` class and offers both Map-based and Object-based internal implementations for performance tuning. It provides methods for setting, getting, deleting, and managing cache entries, along with properties for cache size and configuration.","status":"active","version":"3.7.0","language":"javascript","source_language":"en","source_url":"git://github.com/kibertoad/toad-cache","tags":["javascript","LRU","FIFO","cache","client","server","least","recently","used","typescript"],"install":[{"cmd":"npm install toad-cache","lang":"bash","label":"npm"},{"cmd":"yarn add toad-cache","lang":"bash","label":"yarn"},{"cmd":"pnpm add toad-cache","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ESM named import is preferred. CommonJS require for classes needs direct property access since v3.0.0.","wrong":"const Lru = require('toad-cache').Lru","symbol":"Lru","correct":"import { Lru } from 'toad-cache'"},{"note":"Both LRU and FIFO caches are named exports; there is no default export. Do not use default import syntax.","wrong":"import Fifo from 'toad-cache'","symbol":"Fifo","correct":"import { Fifo } from 'toad-cache'"},{"note":"LruHitStatistics is a separate class for caches requiring hit/miss/expiration tracking, distinct from the base Lru class. HitStatisticsRecord is also a named export for shared statistics.","wrong":"import { Lru, HitStatisticsRecord } from 'toad-cache'","symbol":"LruHitStatistics","correct":"import { LruHitStatistics } from 'toad-cache'"}],"quickstart":{"code":"import { Lru, Fifo, LruHitStatistics, HitStatisticsRecord } from 'toad-cache';\n\n// Basic LRU Cache\nconst lruCache = new Lru(100, 5000); // Max 100 items, 5 seconds TTL\nlruCache.set('key1', 'value1');\nconsole.log('LRU get key1:', lruCache.get('key1'));\nlruCache.set('key2', { data: 'value2' });\nconsole.log('LRU size:', lruCache.size);\nlruCache.delete('key1');\nconsole.log('LRU keys after delete:', lruCache.keys());\n\n// Basic FIFO Cache\nconst fifoCache = new Fifo(50); // Max 50 items\nfifoCache.set('fkey1', 'fvalue1');\nfifoCache.set('fkey2', 'fvalue2');\nconsole.log('FIFO get fkey1:', fifoCache.get('fkey1'));\n\n// LRU Cache with Hit Statistics\nconst sharedRecord = new HitStatisticsRecord();\nconst statsCache = new LruHitStatistics({\n  cacheId: 'my-app-cache',\n  globalStatisticsRecord: sharedRecord,\n  statisticTtlInHours: 1, // Reset stats hourly\n  max: 10,\n  ttlInMsecs: 10000 // 10 seconds TTL\n});\n\nstatsCache.set('skey1', 'svalue1');\nstatsCache.get('skey1'); // Hit\nstatsCache.get('skey2'); // Miss\nconsole.log('Cache statistics:', sharedRecord.getStatistics()['my-app-cache']);","lang":"typescript","description":"Demonstrates the instantiation and basic usage of LRU and FIFO caches, including setting, getting, deleting, and integrating with the optional hit/miss/expiration statistics tracking."},"warnings":[{"fix":"Update your instantiation code from `const cache = Lru(max, ttl)` to `const cache = new Lru(max, ttl)`. Ensure you are importing the classes as named exports: `import { Lru, Fifo } from 'toad-cache'`.","message":"Version 3.0.0 introduced a breaking change by getting rid of the constructor wrapper. Cache instances are now created directly using the `new` keyword with exported class constructors (`Lru`, `Fifo`, `LruHitStatistics`), instead of relying on factory functions.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Be aware that expired items might still reside in the cache until accessed or evicted. If strict real-time expiration is required, consider implementing a background cleanup or checking `expiresAt()` manually.","message":"The `ttl` (Time To Live) property defines how long an item remains in cache, but expiration is 'lazy'. An item will only be removed upon its next `get()` attempt after the TTL has passed, or during an eviction if the cache reaches its `max` size.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Assign a distinct `cacheId` for each `LruHitStatistics` instance sharing a `globalStatisticsRecord`. Understand that `statisticTtlInHours` dictates the rotation of aggregated usage data, not the expiration of individual cache items.","message":"When using `LruHitStatistics`, ensure that `cacheId` is unique if you intend to track multiple caches with a single `HitStatisticsRecord` instance, as statistics are aggregated by this ID. Also, `statisticTtlInHours` defines how often statistics are reset, which might not align with cache item TTL.","severity":"gotcha","affected_versions":">=3.1.0"}],"env_vars":null,"search_vec":"'3.0.0':74 '3.7.0':49 'ad':55 'ad-hoc':54 'addit':60 'allow':84 'along':140 'also':103 'api':101 'appear':51 'base':100,119,123 'browser':37 'bug':62 'cach':2,6,8,29,106,138,144,151 'class':83,99,113 'class-bas':98 'client':35,152 'client-sid':34 'configur':147 'current':45 'delet':135 'differenti':71 'direct':77,85 'driven':57 'entri':139 'environ':43 'export':78 'factori':92 'featur':59 'fifo':5,28,82,150 'first':24,26 'first-in-first-out':23 'fix':63 'function':93 'get':134 'hit/miss/expiration':109 'hoc':56 'idiomat':97 'implement':125 'in-memori':14 'instanti':86 'intern':124 'javascript':148 'javascript/typescript':11 'key':70 'least':18,154 'least-recently-us':17 'librari':12 'lru':3,21,80,149 'lruhitstatist':112 'manag':137 'map':118 'map-bas':117 'memori':16 'method':131 'new':88 'node.js':42 'object':122 'object-bas':121 'offer':13,115 'option':105 'perform':127 'properti':142 'provid':94,130 'rather':64,89 'recent':19,155 'releas':50 'schedul':68 'server':40,153 'server-sid':39 'set':133 'side':36,41 'sinc':72 'size':145 'stabl':46 'statist':107 'strategi':30 'strict':67 'suitabl':31 'support':104 'toad':1,7 'track':108 'tune':128 'typescript':157 'use':20,156 'version':47,73 'via':110","created_at":"2026-04-19T13:41:41.662170+00:00","updated_at":"2026-04-19T13:41:41.662170+00:00","problems":[{"fix":"Use the `new` keyword to instantiate: `const cache = new Lru(max, ttl)`. Ensure you are using named imports for ESM: `import { Lru } from 'toad-cache'` or correctly accessing the class property for CJS: `const Lru = require('toad-cache').Lru`.","cause":"Attempting to instantiate `Lru` as a function instead of a class, or importing incorrectly after version 3.0.0.","error":"TypeError: Lru is not a function"},{"fix":"Double-check the import statement. For Toad Cache, `Lru` and `Fifo` are named exports. If you're importing a specialized version like `LruHitStatistics`, ensure that's what you're referencing: `import { Lru, Fifo, LruHitStatistics } from 'toad-cache'`.","cause":"Trying to import a non-existent named export, possibly due to a typo or misunderstanding of the package's exports.","error":"SyntaxError: Named export 'Lru' not found. The requested module 'toad-cache' does not provide an export named 'Lru'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/kibertoad/toad-cache","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/toad-cache","openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}