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

nest-cacheable

v1.0.0

Published

Advanced caching decorators for NestJS applications with support for TTL, conditional caching, stale-while-revalidate, and more

Readme

NestJS Cacheable

Advanced caching decorators for NestJS applications with support for TTL, conditional caching, stale-while-revalidate, and more.

Features

  • 🚀 Simple Integration - Easy-to-use decorators for caching method results
  • Performance Optimized - Reduce database queries and API calls
  • 🎯 Conditional Caching - Cache based on custom conditions
  • 🔄 Stale-While-Revalidate - Serve stale content while refreshing in background
  • 🗑️ Cache Eviction - Clear cache entries programmatically
  • 📊 Event Callbacks - Monitor cache hits, misses, and errors
  • 🔧 Customizable - Configure TTL, cache keys, and serialization
  • 🌐 Multiple Stores - Support for Redis, Memory, and other cache stores

Installation

# Using pnpm (recommended)
pnpm add nest-cacheable

# Using npm
npm install nest-cacheable

# Using yarn
yarn add nest-cacheable

Quick Start

1. Import CacheModule

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';

@Module({
  imports: [
    CacheModule.register({
      ttl: 300, // seconds
      max: 100, // maximum number of items in cache
    }),
  ],
})
export class AppModule {}

2. Use Cacheable Decorator

import { Injectable } from '@nestjs/common';
import { Cacheable, Time } from 'nest-cacheable';

@Injectable()
export class UserService {
  @Cacheable({
    ttl: 5 * Time.MINUTE,
    cacheKey: (userId) => `user:${userId}`,
  })
  async getUser(userId: string) {
    // This expensive operation will be cached
    return await this.database.findUser(userId);
  }
}

Decorators

@Cacheable

Cache method results with advanced options:

@Cacheable({
  // Cache expiration time in seconds
  ttl: 60,

  // Custom cache key
  cacheKey: (id) => `product:${id}`,

  // Conditional caching
  cacheIf: (id) => id !== 'admin',

  // Event callbacks
  onHit: (key) => console.log(`Cache hit: ${key}`),
  onMiss: (key) => console.log(`Cache miss: ${key}`),
  onError: (error) => console.error(`Cache error: ${error}`),

  // Stale-while-revalidate
  staleWhileRevalidate: 30,
  backgroundRefetch: true,

  // Background refresh interval
  refetchInterval: 60,

  // Custom serialization
  serialize: (data) => JSON.stringify(data),
  deserialize: (cached) => JSON.parse(cached),
})
async getProduct(id: string) {
  return await this.productRepository.findOne(id);
}

@CacheEvict

Clear cache entries:

@CacheEvict({
  // Cache key to evict
  cacheKey: (id) => `product:${id}`,

  // Clear before method execution
  beforeInvocation: false,

  // Clear all cache entries
  all: false,

  // Exact key match or pattern
  exact: true,
})
async updateProduct(id: string, data: UpdateProductDto) {
  return await this.productRepository.update(id, data);
}

Advanced Usage

Time Utilities

import { Time } from 'nest-cacheable';

@Cacheable({
  ttl: 2 * Time.HOUR,  // 2 hours
  // or
  ttl: 30 * Time.MINUTE,  // 30 minutes
  // or
  ttl: 7 * Time.DAY,  // 7 days
})

Multiple Cache Keys

@Cacheable({
  cacheKey: (userId, filters) => [
    `user:${userId}`,
    `filters:${JSON.stringify(filters)}`,
  ],
})
async getUserData(userId: string, filters: any) {
  // Method implementation
}

Conditional Caching

@Cacheable({
  cacheIf: async (userId) => {
    // Only cache for non-admin users
    const user = await this.getUser(userId);
    return user.role !== 'admin';
  },
})
async getSensitiveData(userId: string) {
  // Method implementation
}

Stale-While-Revalidate Pattern

@Cacheable({
  ttl: 60,  // Cache for 60 seconds
  staleWhileRevalidate: 30,  // Serve stale for 30 more seconds
  backgroundRefetch: true,  // Refresh in background
})
async getFrequentlyAccessedData() {
  // Method implementation
}

Cache Eviction Patterns

// Clear specific cache entry
@CacheEvict({
  cacheKey: (id) => `item:${id}`,
})
async deleteItem(id: string) {
  // Method implementation
}

// Clear all cache entries
@CacheEvict({
  all: true,
})
async clearAllCache() {
  // Method implementation
}

// Clear before method execution
@CacheEvict({
  cacheKey: (id) => `item:${id}`,
  beforeInvocation: true,
})
async updateItem(id: string, data: any) {
  // Method implementation
}

Redis Configuration

For production use, Redis is recommended:

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { redisStore } from 'cache-manager-redis-store';

@Module({
  imports: [
    CacheModule.register({
      store: redisStore,
      host: 'localhost',
      port: 6379,
      ttl: 600,
    }),
  ],
})
export class AppModule {}

Best Practices

  1. Choose appropriate TTL values - Consider data freshness requirements
  2. Use meaningful cache keys - Include all parameters that affect the result
  3. Monitor cache performance - Use event callbacks to track hit rates
  4. Handle errors gracefully - Implement onError callbacks
  5. Clear cache strategically - Use @CacheEvict after data modifications

API Reference

CacheableOptions

| Option | Type | Description | | ---------------------- | -------------------------------- | --------------------------------------------------- | | ttl | number | Cache expiration time in seconds | | cacheKey | string \| string[] \| Function | Custom cache key definition | | cacheIf | Function | Condition to determine if caching should be applied | | serialize | Function | Custom serialization function | | deserialize | Function | Custom deserialization function | | staleWhileRevalidate | number | Time to serve stale content while refreshing | | backgroundRefetch | boolean | Enable background refresh | | refetchInterval | number | Background refresh interval in seconds | | onError | Function | Error callback | | onSuccess | Function | Success callback | | onHit | Function | Cache hit callback | | onMiss | Function | Cache miss callback |

CacheEvictOptions

| Option | Type | Description | | ------------------ | -------------------------------- | ----------------------------------- | | cacheKey | string \| string[] \| Function | Cache key(s) to evict | | exact | boolean | Use exact key match or pattern | | beforeInvocation | boolean | Clear cache before method execution | | all | boolean | Clear all cache entries |

Examples

Check the examples/ directory for complete working examples:

  • Basic caching
  • Redis integration
  • Conditional caching
  • Cache eviction patterns
  • Stale-while-revalidate

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see the LICENSE file for details.

Support

For issues and feature requests, please use the GitHub issue tracker.