memorystore

A leak-free, LRU-backed session store for express-session, with configurable TTL and pruning.

Library
npm
v1.6.8
121stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
51/100Fair
Development Activity44
Maintenance24
Community56
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture68
Code Quality62
Innovation58
Learning Curve85

memorystore replaces the default in-memory session store that ships with express-session, which has no way to expire old sessions and grows unbounded over the lifetime of a process. It wraps isaacs’s lru-cache behind the standard express-session Store interface, so every session write goes through a cache with a real max size and a real ttl, and expired or overflowed entries fall out automatically instead of accumulating.

Because it implements every required, recommended, and optional method of the express-session store contract (get, set, destroy, touch, all, length, clear, ids), it’s a drop-in swap for the default store in any existing Express app — the same session middleware setup, just with bounded memory. It adds a checkPeriod option to run a periodic sweep that proactively evicts expired sessions (disabled by default, since lru-cache already evicts lazily on access), plus prune(), startInterval(), and stopInterval() for manual control over that sweep from application code.

Sessions still live in a single process’s memory, so it isn’t a substitute for a shared store like Redis in a multi-process or multi-server deployment — it solves the leak, not the sharing problem. That tradeoff is exactly why it fits: single-instance apps, local development, and tests that want session support without standing up an external store.

What You Get

  • A full express-session Store implementation — get, set, destroy, touch, all, length, clear, and ids — so it’s a drop-in replacement for the default store
  • max and ttl options that bound memory by cache size and session age, defaulting ttl to the session cookie’s maxAge when one isn’t given
  • An optional periodic checkPeriod sweep that proactively prunes expired sessions, plus a manual prune() method to trigger the same sweep on demand
  • A dispose callback invoked when a session falls out of the cache, useful for cleanup work like closing file descriptors tied to a session
  • Pluggable serializer support (defaults to JSON) for controlling how session objects are stringified into the cache
  • TypeScript type definitions (index.d.ts) describing the store’s options and shape out of the box

Common Use Cases

  • Adding session support to a single-instance Express app without needing to run Redis or another external store
  • Local development and CI test environments where a lightweight in-memory session store is enough
  • Replacing the default express-session MemoryStore in an existing app that’s leaking memory from sessions that never expire
  • Prototypes and small internal tools where session data doesn’t need to survive a restart or be shared across processes

Under The Hood

Architecture The package is a small factory-function wrapper, not a class exported directly: lib/memorystore.js exports a function that takes the caller’s express-session module and returns a MemoryStore class extending session.Store, which is how express-session’s official store contract expects the pattern (require('memorystore')(session)). Internally, each instance holds a single lru-cache instance (this.store) as its actual backing store, and every public method (get, set, destroy, touch, all, length, clear, ids) is a thin, direct translation from the express-session Store API to the corresponding lru-cache call, with a small runCallback/defer helper standing in for Node’s callback-based async convention (deferring via setImmediate rather than calling back synchronously, avoiding Zalgo). A module-level getTTL helper centralizes the ttl-resolution precedence (explicit option, function, cookie maxAge, one-day default) so it’s evaluated identically on every set/touch call.

Tech Stack The only runtime dependencies are debug (namespaced memorystore logging, gated by the DEBUG env var) and lru-cache (pinned to the legacy ^4.0.3 API, which differs materially from lru-cache’s current major versions — the constructor is invoked as a function LRU(options), not new LRU(), and max accepts Infinity). There is no build step: it ships as plain CommonJS JavaScript with a hand-written index.d.ts for TypeScript consumers. Linting is enforced via standard and tests run under mocha (mocha --check-leaks --bail --no-exit), with Travis CI as the historical CI provider referenced in the README badge.

Code Quality The single test file (test/store.js) instantiates the store directly against a stub { Store: class {} } in place of a real express-session module and exercises the documented option defaults, the max eviction boundary, destroy on both single and array session IDs, and the checkPeriod/prune interval behavior — a focused but not exhaustive suite, with no coverage tooling wired into CI. Error handling is explicit rather than swallowed: get, set, and touch all wrap serialization in try/catch and pass the error to the callback rather than throwing, matching the Node callback-error convention express-session expects. Naming and style are enforced by standard (zero-config ESLint preset), and the codebase is small enough (a single ~250-line core file) that its conventions are consistent throughout.

API Design The public API mirrors express-session’s own Store contract almost exactly, so there’s essentially no new API surface to learn beyond new MemoryStore(options) — anyone who already knows express-session’s store interface can read this package’s README in a few minutes. The three added conveniences (checkPeriod, prune(), startInterval/stopInterval) are optional and orthogonal to the required interface, so the default configuration works with zero tuning. Documentation is a single, complete README section per option, and the TypeScript definitions give editor autocomplete for every constructor option without needing to read the source.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search