Skip to content

Overview

effector-tanstack-query is a thin adapter that exposes TanStack Query as effector units. It does not reimplement the cache, dedup, or revalidation logic — it forwards them.

What you get

  • Stores instead of result objects. Every observer field (data, status, isPending, …) becomes a Store<T> you can combine and sample from.
  • Events instead of imperative methods. mounted / unmounted / mutate / refresh / fetchNextPage are EventCallables — call them directly or wire them via sample.
  • Reactive query keys. A Store placed inside queryKey triggers a refetch when it updates. No manual invalidateQueries.
  • Parallel query families. createQueries({ source, query }) drives a reactive list of queries off a single Store — items added to / removed from the source spawn / dispose their observers automatically.
  • SSR via two layers. Hydrate queryClient with dehydrate + <HydrationBoundary> AND restore effector scope via serialize(scope) / fork({ values }).
  • React entry point. Optional @effector-tanstack-query/react package ships useQuery, useMutation, useSuspenseQuery, etc. — same data, just with auto mount/unmount.

What this is not

  • Not a different cache. Behavior, semantics, and options come straight from TanStack Query (@tanstack/query-core). If TanStack Query supports staleTime: Infinity, so do we — same defaults, same edge cases.
  • Not React-bound. Core works in any environment with effector. React is opt-in via the /react subpackage.

Comparison

Conceptreact-queryeffector-tanstack-query
Read query stateconst { data } = useQuery(...)useUnit(query.$data) or useQuery(query)
Reactive keyuseState + queryKey: [..., id]Store directly inside queryKey
Trigger fetchimplicit on mountquery.mounted() (or via useQuery hook)
InvalidatequeryClient.invalidateQueries(...)query.refresh()
React to outcomecallbacks per mutate(vars, opts)sample({ clock: m.finished.success, ... })
Parallel queriesuseQueries([...])createQueries({ source, query }) + useQueries
SSR hydration<HydrationBoundary><HydrationBoundary> + fork({ values: ... })

Both run on top of the same @tanstack/query-core cache.

Runnable examples

Two reference apps live in examples/ in the repository:

  • examples/csr — Vite + React. Covers every common pattern: reactive pagination, dependent queries, placeholderData, reactive polling, infinite query, Suspense + ErrorBoundary, mutations + invalidation, optimistic update with rollback, per-call callbacks. MSW handles the mutation endpoints — no backend setup.
  • examples/ssr — Next.js 16 App Router. Per-request QueryClient + effector scope, query.prefetch for awaited SSR prefetching, dehydrate + serialize, hydration with no flash on first paint.