Angular 22+ · Zero dependencies · Signal-native · Tree-shakeable
SWR caching for Angular resource()
Stale-while-revalidate for resource(). Instant navigations, silent background refreshes.
Go back to a page you already visited and you get the spinner again. ziflux paints the cached value immediately and refreshes behind it, for as long as the entry is within expireTime.
If you know resource() and signals, most of this is already familiar. Three APIs, no runtime dependencies, 6.2 kB brotli enforced in CI.
npm install ngx-zifluxconst todos = cachedResource({
cache: this.#api.cache,
cacheKey: params => ['todos', params.status],
params: () => this.filters(),
loader: ({ params }) => this.#api.getAll$(params),
})What it feels like
Same app, same actions. One caches.
How caching works #
Two timers, three phases. invalidate() marks entries stale — it never deletes them.
FRESH
Return cached data
No network request
STALE
Return cached + re-fetch
User sees data instantly, refresh in background
staleTime elapsed — data may be outdatedEVICTED
Fetch from server
Cache entry removed
expireTime elapsed — entry evictedThe docs add the loading-state table, cache keys and when to cache.
When ziflux is the wrong tool #
SWR caching is narrow on purpose. If your problem looks like one of these, reach for something else.
| Limit | Why not | Use instead |
|---|---|---|
| Real-time data (WebSocket / SSE) | SWR assumes data ages on a wall clock. Push streams update on events, not on staleness. | Subscribe to the stream directly. Cache the snapshot if you need offline display. |
| SSR transfer state | ziflux is in-memory and does not serialize across the server/client boundary. | Use Angular's TransferState for SSR hydration; layer ziflux on top after rehydration. |
| Persistence across browser reloads | The cache lives in process memory and is gone on refresh. | Persist explicitly with localStorage / IndexedDB; ziflux handles the in-memory layer above. |
| Volatile search-as-you-type | New params on every keystroke means new cache keys. LRU thrashes; the cache becomes overhead. | Debounce the input; cache only the stable result keys you actually want to revisit. |
| Angular before v22 | ziflux declares @angular/core ^22.0.0 as its peer range, so npm will refuse to install it on older majors. The code itself only needs resource(), which shipped earlier, but v22 is the supported floor. | Stay on whatever cache pattern you have today; revisit when you upgrade. |
| Global state orchestration | ziflux caches data; it does not coordinate workflows, side-effects, or cross-feature actions. | NgRx, NgRx SignalStore, or a state machine. Pair it with ziflux for the data layer. |
How ziflux compares #
You'll compare anyway, so here is the honest positioning.
TanStack Query (Angular)
Full data-fetching framework. Infinite queries, SSR hydration, persistence, cross-framework. Pick this if your data layer needs the whole toolbox. Its Angular adapter still ships as @tanstack/angular-query-experimental.
NgRx
Two things under one name: the classic Redux store (reducers, effects, selectors, time-travel) and @ngrx/signals SignalStore, which is signal-first. Pick either when caching is a side-effect of complex global state, not the goal. ziflux has no integration layer for it and does not need one: cachedResource() and DataCache only require an Angular injection context, so anything that provides one can host them.
ziflux
Caches resource(). That's the entire scope. Signal-native, no new mental model. Pick this when SWR on top of Angular's built-in primitives is all you need.
Mutation lifecycle (onMutate → mutationFn → onSuccess → invalidateKeys) is modeled on React Query: a proven shape with signal-native execution.
GitHub · MIT License · Zero dependencies
AI skills #
Give your AI coding agent deep ziflux expertise. Works with Claude Code, Cursor, Windsurf, and any skills.sh-compatible tool.
npx skills add https://github.com/neogenz/ziflux --skill ziflux-expertAdd it to one resource()
Caches resource(). Nothing else. Zero dependencies, 6.2 kB brotli, three APIs.
npm install ngx-ziflux