Skip to content

effector-tanstack-query

Reactive data fetching with effector stores. Powered by TanStack Query — the same battle-tested cache, deduplication, and lifecycle, exposed as effector units.

Reactive query keys

Drop an effector Store into queryKey — the query refetches automatically when the store changes.

SSR built-in

Round-trip the queryClient cache (dehydrate/hydrate) and the effector scope (serialize/fork) for hydration without a flash.

Suspense ready

useSuspenseQuery and useSuspenseInfiniteQuery plug straight into React <Suspense> and error boundaries.

Effector-idiomatic

finished.success / finished.failure events compose with sample — declarative reactions, no component callbacks.

At a glance

import { QueryClient } from '@tanstack/query-core'
import { setQueryClient, createQuery } from '@effector-tanstack-query/core'
import { createStore, createEvent } from 'effector'
const queryClient = new QueryClient()
queryClient.mount()
setQueryClient(queryClient)
const setUserId = createEvent<number>()
const $userId = createStore(1).on(setUserId, (_, id) => id)
const userQuery = createQuery({
name: 'user',
queryKey: ['user', $userId],
queryFn: ({ queryKey }) => fetch(`/api/users/${queryKey[1]}`).then((r) => r.json()),
})
userQuery.mounted()
setUserId(2) // → triggers a refetch with the new key

Why this exists

TanStack Query is the de-facto standard for client-side data fetching, but its native API is built around React render cycles and hooks. Effector applications usually keep state outside the component tree — and want the same cache, deduplication, and revalidation as effector stores and events.

This library is a thin adapter that:

  • exposes every observer field (data, status, isPending, isFetching, isPlaceholderData, …) as a Store<T>,
  • forwards every imperative action (refetch, fetchNextPage, mutate, reset, …) as an EventCallable,
  • and lets you compose with the rest of effector via sample and combine — without re-implementing the cache.