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

ngx-ziflux

v0.0.12

Published

SWR caching layer for Angular's resource() API. Zero dependencies. Signal-native.

Readme

ziflux

npm version license Angular CI

A zero-dependency, signal-native caching layer for Angular 21+. Stale-while-revalidate semantics for resource() — instant navigations, background refreshes, no spinners on return visits.

Documentation · npm · GitHub


Quick Start

npm install ngx-ziflux
import { provideZiflux, withDevtools } from 'ziflux'

// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [provideZiflux({ staleTime: 30_000, expireTime: 300_000 }, withDevtools())],
}
import { inject, Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { DataCache, cachedResource } from 'ziflux'

// todo.api.ts — singleton, owns the cache
@Injectable({ providedIn: 'root' })
export class TodoApi {
  readonly cache = new DataCache()
  readonly #http = inject(HttpClient)
  getAll$() { return this.#http.get<Todo[]>('/todos') }
}

// todo-list.store.ts — route-scoped, reads the cache
readonly todos = cachedResource({
  cache: this.#api.cache,
  cacheKey: ['todos'],
  loader: () => this.#api.getAll$(),
})

All DataCache instances inherit defaults from provideZiflux(). Devtools are only active in dev mode.

See the full example app for a working Todo demo with mutations, optimistic updates, polling, and devtools.


Architecture

Component → Store → API Service → DataCache → Server

Each layer has a clear scope: components own the view, stores own the route state, API services (root singletons) own the cache. Signals flow back from Store to Component. The cache is transparent to the Store.

See the Architecture Guide for the full domain pattern.


Why ziflux?

  • Instant navigations — cached data appears immediately, fresh data loads in the background. No spinners on return visits.
  • Optimistic updates in 5 linescachedMutation handles the snapshot → mutate → rollback-on-error lifecycle for you.
  • Zero plumbing — you stop hand-rolling stale-while-revalidate logic, duplicating it across projects, and maintaining it forever.

resource() handles the fetch lifecycle. ziflux handles the data lifecycle — when to re-fetch, what to keep, what's stale. Angular signals remain your state layer.


How is this different?

| | ziflux | TanStack Query | NgRx | | --- | --- | --- | --- | | Mental model | resource() + cache | Query client | Actions + reducers + effects | | Angular signals | Native | Adapter | Adapter (SignalStore) | | Dependencies | 0 | 3+ | 5+ | | Learning curve | Minutes | Hours | Days | | API surface | 9 exports | 50+ | 100+ | | Use case | SWR caching for resource() | Full data-fetching framework | Full state management | | Best for | SWR on resource() | Full data-fetching layer | Complex state + effects |

Pick ziflux when you want caching semantics on top of Angular's built-in resource() — nothing more, nothing less. Pick TanStack Query when you need a comprehensive data-fetching layer with pagination, infinite queries, and devtools across frameworks. Pick NgRx when you need full-blown state management with time-travel debugging, entity adapters, and complex side-effect orchestration.


API at a Glance

| Export | Description | | --- | --- | | DataCache | Per-domain cache instance — owns entries, invalidation, dedup | | cachedResource() | resource() + SWR cache awareness. Returns CachedResourceRef<T> | | cachedMutation() | Declarative mutation lifecycle — status signals, optimistic updates, auto-invalidation | | provideZiflux() | Global config — staleTime, expireTime, maxEntries | | withDevtools() | Cache inspector + structured console logging (dev mode only) | | anyLoading() | Aggregate Signal<boolean> from multiple loading/pending signals | | ZIFLUX_CONFIG | Injection token for the resolved config | | CacheRegistry | Tracks all DataCache instances — used internally by devtools | | ZifluxDevtoolsComponent | Standalone component — renders cache inspector overlay in dev mode |

Full signatures, return types, and usage examples → API Reference


Freshness Model

Entries move through three states: FreshStaleEvicted. staleTime and expireTime control the transitions.

  • Fresh — returned directly from cache, no fetch
  • Stale — returned immediately + background fetch (SWR)
  • Evicted — cache miss, full fetch from server

Golden rule: invalidate() marks entries stale. It never deletes them. Users always see data instantly — even stale — while fresh data loads.

See the Freshness Guide for TTL configuration and examples.


Cache Keys

Hierarchical arrays. Serialized with JSON.stringify. Prefix-based invalidation.

['order', 'list', 'pending']  // filtered list
['order', 'details', '42']   // single entity
['order']                     // invalidate(['order']) → matches both above

Gotchas

  • invalidate([]) is a no-op. An empty prefix matches nothing. Use cache.clear() to wipe everything.
  • invalidate() is prefix-based, not exact-match. invalidate(['order', 'details', '42']) also matches ['order', 'details', '42', 'comments'].
  • ref.set() / ref.update() write to the cache. They update both the Angular resource and the DataCache — optimistic values survive cache version bumps from unrelated invalidations. To trigger a fresh server fetch, call invalidate().
  • value() preserves cached data on error. When a background revalidation fails, value() returns the last cached value (not undefined). Check error() to detect the failure and show an error banner alongside the stale data.
  • Cache keys are untyped at the boundary. Type correctness depends on consistent key→type pairings in your code.

Documentation

  • Guide — Domain pattern, 3-file structure, full usage walkthrough (API → Store → Template → Mutations → Optimistic updates)
  • Testing — TestBed setup, store testing, standalone DataCache testing
  • Caching — Freshness model, loading states, cache keys, when to cache
  • API Reference — Full signatures, return types, usage examples for all 9 exports

Prior Art

  • RFC 5861 — stale-while-revalidate HTTP cache-control extension
  • TanStack QuerystaleTime, gcTime, structured query keys
  • SWR by Vercel — popularized SWR in the frontend ecosystem
  • Angular resource() — the foundation this library builds on

Zero external dependencies. 100% Angular signals + resource() + in-memory Map.

AI code generation instructions: llms.txt


AI Skills

Install the ziflux expert skill for your AI coding agent:

npx skills add neogenz/ziflux

Gives your agent deep knowledge of ziflux APIs, patterns, and best practices for implementation, debugging, code review, and testing.


Limitations

  • Client-side only — no SSR transfer state. The cache is in-memory and does not serialize across server/client boundaries.

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.