npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cache-registry

v5.0.0

Published

Cache registry class to facilitate caching withing application. using singleton pattern to ensure usage of same instance. Must important feature is to get/set cache in one go using callback functions

Readme

statements branches functions lines

Cache Registry

A minimalistic, framework-agnostic caching utility for Node.js applications. Supports both in-memory and Redis-based caching with a simple, unified API.


Table of Contents


Features

  • In-memory and Redis cache support
  • Singleton instance management: Identical options return the same instance
  • Shared Redis connection: All cache instances using Redis, share a single connection
  • TypeScript support
  • Framework agnostic
  • Graceful error handling: Cache failures never break your app

Installation

npm install cache-registry

Quick Start

TCacheInputOptions

The TCacheInputOptions type defines the configuration options for initializing a cache registry instance. These options let you control the cache type, expiration, key management, and whether caching is enabled/disabled making it easy to tailor caching behavior for different environments (e.g., disabling cache in local development to test new features).

type TCacheInputOptions = IInMemoryCacheOptions | IRedisCacheOptions;

interface IInMemoryCacheOptions {
  /**
   * The cache backend type: 'in-memory'.
   */
  type: CacheTypeEnum.IN_MEMORY;
  /**
   * Default time-to-live (TTL) for cached items, in seconds.
   */
  cacheTtl: number;
  /**
   * Enable or disable caching. Useful for turning off cache in development or testing environments.
   */
  isCacheEnable: boolean;
  /**
   * (Optional) Prefix to add to all cache keys.
   */
  keyPrefix?: string;
}

interface IRedisCacheOptions {
  /**
   * The cache backend type: 'redis'.
   */
  type: CacheTypeEnum.REDIS;
  /**
   * Default time-to-live (TTL) for cached items, in seconds.
   */
  cacheTtl: number;
  /**
   * Enable or disable caching. Useful for turning off cache in development or testing environments.
   */
  isCacheEnable: boolean;
  /**
   * Required prefix to add to all cache keys. Mandatory for Redis to avoid key collisions.
   */
  keyPrefix: string;
  /**
   * Redis connection options.
   */
  redisOptions: RedisClientOptions;
}

Usage tip:

  • Set isCacheEnable: false in your local .env or configuration to disable caching during development, ensuring you always fetch fresh data while testing new features. In production, set isCacheEnable: true for optimal performance.

Examples

Comprehensive examples demonstrating common patterns are available in the examples/ directory:

Run examples:

npm run build
npx tsx examples/01-basic-usage.ts

See the examples README for detailed documentation.


Usage

In-Memory Cache Example

import { getCacheRegistry, CacheTypeEnum } from 'cache-registry';

// Initialize cache
function initCache() {
  const cache = getCacheRegistry({
    type: CacheTypeEnum.IN_MEMORY,
    isCacheEnable: true,
    cacheTtl: 60, // seconds
  });

  return cache;
}

Redis Cache Example

import { getCacheRegistry, CacheTypeEnum } from 'cache-registry';

function initCache() {
  const cache = getCacheRegistry({
    type: CacheTypeEnum.REDIS,
    isCacheEnable: true,
    cacheTtl: 120,
    keyPrefix: 'myapp',
    redisOptions: { url: 'redis://localhost:6379' }, // Standard redis client options
  });

  return cache;
}

Recommended Setup

To avoid repeated configuration, initialize and export your cache instance from a utility/provider module:

// utils/cache.ts
import { getCacheRegistry, CacheTypeEnum } from 'cache-registry';

export const cache = getCacheRegistry({
    type: CacheTypeEnum.IN_MEMORY,
    isCacheEnable: process.env.CACHE_ENABLE === 'yes',
    cacheTtl: process.env.CACHE_EXPIRATION ? parseInt(process.env.CACHE_EXPIRATION) : 60,
  });

Then, use your cache instance anywhere in your application:

import { cache } from './utils/cache';

async function getColor() {
  return await cache.get('color');
}

async function setColor(colors: string[]) {
  await cache.set('color', colors);
}

Multiple Cache Instances

You can create multiple cache instances for different data lifecycles (e.g., short TTL for DB data, long TTL for API responses):

import { getCacheRegistry, CacheTypeEnum } from 'cache-registry';

const dbCache = getCacheRegistry({
  type: CacheTypeEnum.IN_MEMORY,
  isCacheEnable: true,
  cacheTtl: 60, // 1 minute
});

const httpCache = getCacheRegistry({
  type: CacheTypeEnum.IN_MEMORY,
  isCacheEnable: true,
  cacheTtl: 3600, // 1 hour
});

How Instance Management Works

getCacheRegistry(options) returns the same instance for identical options. Internally, a Map keyed on type + cacheTtl + keyPrefix + isCacheEnable + redisUrl ensures singleton behavior.

  • type: CacheTypeEnum.IN_MEMORY or CacheTypeEnum.REDIS
  • cacheTtl: Time-to-live in seconds
  • keyPrefix: (optional for in-memory, required for Redis) Prefix for all cache keys
  • isCacheEnable: Included in the key — different enable/disable settings produce separate instances

For Redis, all cache registries that connect to the same Redis server (e.g., the same url, such as redis://localhost:6379) will share a single Redis connection. This means you won't have multiple open connections to the same Redis instance, even if you create several cache instances pointing to the same server—helping to reduce resource usage and avoid unnecessary connections.

Connection Resilience

When using Redis, the cache automatically handles connection issues:

  • On disconnection: Logs a single error message (avoids log spam during reconnection attempts)
  • During downtime: Cache operations gracefully degrade—get() returns null or executes fallback, set() silently skips caching
  • On reconnection: Automatically restores connection and resumes caching
  • Shared error handling: Multiple cache instances share connection state, so you only see one error log regardless of how many instances you have

API Reference

getCacheRegistry(options: TCacheInputOptions)

Returns a cache registry instance. For identical options, returns the same singleton instance.

Options:

  • type: CacheTypeEnum.IN_MEMORY | CacheTypeEnum.REDIS
  • isCacheEnable: boolean - Enable/disable caching
  • cacheTtl: number - Time-to-live in seconds
  • keyPrefix: string - Required for Redis, optional for in-memory
  • redisOptions: RedisClientOptions - Required for Redis. See Redis client options

destroyCacheRegistry(): Promise<void>

Async. Clears all cached registry instances and disconnects the Redis connection. Useful for testing or graceful shutdown. Always await this call.

Instance Methods

  • get<T>(key: string, fallback?: () => Promise<T>): Promise<T | null> — Retrieve a value by key from the cache.
    • Without a callback: Returns the cached value if present, or null if not found.
    • With a callback: If the value is not present in the cache, the callback is executed to fetch or compute the value, which is then cached and returned. If the value is already cached, the callback is not executed and the cached value is returned immediately. This allows you to implement a lazy caching pattern (get-or-set) in a single call.
    Example:
    // Only fetches from DB if not cached
    const data = await cache.get('my-key', async () => {
      return await db.getExpensiveData();
    });
  • set<T>(key: string, value: T): Promise<void> — Store a value by key in the cache.
  • delete(key: string): Promise<void> — Delete an element from the cache by its key.
  • clear(): Promise<void> — Remove all values from the cache (clear the cache).
  • getKeys(): Promise<string[]> — Return all keys currently stored in this cache registry instance.

Best Practices

  • Export a singleton cache instance from a utility module for reuse.
  • Use keyPrefix always use key prefix to avoid cache instances collisions specially when using redis.
  • Handle cache errors gracefully: Cache Registry is designed not to throw on cache failures.
  • Configure TTLs appropriately for different data sources.

FAQ

Q: What happens if Redis is down?
A: Cache operations gracefully degrade—get() returns null/fallback, set() silently skips. Only one error is logged (no spam during retries). The cache automatically reconnects when Redis becomes available again—no manual intervention required.

Q: Can I use this in any Node.js framework?
A: Yes, Cache Registry is framework-agnostic.


License

MIT