A slim, signal-based caching library for Angular.
npm install ngx-cachr- Signal-Based: Fully built on signals for modern and granular reactivity.
- Flexible Strategies: Support for
cache-first,network-first, andstale-while-revalidate(SWR). - Multi-Layer Caching: Memory cache using LRU and persistent cache via LocalStorage.
- Lightweight: Minimal footprint, tree-shakeable.
Add provideNgxCachr to your application configuration (usually app.config.ts).
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideNgxCachr } from 'ngx-cachr';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideNgxCachr({
prefix: 'angular-app:', // prefix for storage keys (whatever you want)
defaultTtl: 300000, // 5 minutes
defaultStrategy: 'swr', // stale while revalidate
debug: true // adds logging
})
]
};Use the cachedResource function to fetch and cache data. It returns a CachedResource object with data, status, and error signals.
import { Component, computed, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { cachedResource } from 'ngx-cachr';
@Component({
selector: 'app-user-profile',
standalone: true,
imports: [CommonModule],
template: `
@if (user.status() === 'loading') {
<p>Loading...</p>
} @else if (user.error()) {
<p>Error loading user</p>
} @else if (user.data()) {
<h1>{{ user.data()?.name }}</h1>
<p>Email: {{ user.data()?.email }}</p>
<button (click)="user.invalidate()">Refresh</button>
}
@if (user.status() === 'revalidating') {
<small>Updating in background...</small>
}
`
})
export class UserProfileComponent {
http = inject(HttpClient);
// the most simple usage.
// personally, i'd move this to a service, but it's just an example.
user = cachedResource({
key: 'user-current',
loader: () => firstValueFrom(this.http.get<any>('/api/user')),
ttl: 60 * 1000, // keep fresh for 1 minute
});
}Pass a function that returns the options to make the query reactive. When dependencies change (signals used inside), the resource automatically re-fetches.
userId = signal(1);
user = cachedResource(() => ({
key: ['user', this.userId()], // key changes when userId changes
loader: () => this.fetchUser(this.userId())
}));
nextUser() {
// user.data() will automatically update now
this.userId.update(id => id + 1);
}| Option | Type | Default | Description |
|---|---|---|---|
prefix |
string |
'ngx-cachr:' |
Namespace for storage keys. |
version |
number |
1 |
Cache version. Bump to invalidate all persistent storage. |
defaultTtl |
number |
300000 |
Default time-to-live in ms (5 mins). |
defaultStrategy |
'cache-first' | 'network-first' | 'swr' |
'swr' |
Default caching strategy. |
memory.maxEntries |
number |
100 |
Max items in memory (LRU). |
swr(Stale-While-Revalidate): Returns cached data immediately (if available), then fetches from network in the background to update the cache. Best for UI responsiveness.cache-first: Returns cached data if fresh. Only fetches from network if cache is missing or stale.network-first: Always fetches from network. Falls back to cache if network fails.
MIT