Skip to content

vs. farfetched

farfetched is the most complete data-fetching tool for effector and the obvious reference point. It's mature, well-designed, and open-source / not archived. This page is an honest comparison — including where farfetched is still ahead — so you can pick the right tool, not a sales pitch.

The one-line difference: farfetched models a query as its own event-based abstraction (a RemoteOperation built from a handler); effector-refetch wraps your real Effect and exposes friendly inline config. Different philosophy, lots of overlap.

Where farfetched is still ahead

Be aware of these before switching:

  • Maturity & ecosystem. Years in production, a larger community, more accumulated recipes and edge-case fixes. effector-refetch is young (0.x) by comparison.
  • Sourced parameters everywhere. In farfetched almost every field of every operator can be a Store/source. effector-refetch sources the declarative-HTTP fields (url / query / body / headers in createJsonQuery / createJsonMutation) plus a curated config set — enabled, concurrency, retry.times, cache.staleAfter, refetchInterval, timeout — and expects the rest to come from the effect's params (often via sample). Closer than it was, but still narrower.
  • A couple of named validation adapters. farfetched ships dedicated @farfetched/{runtypes,io-ts,superstruct,typed-contracts,zod}. effector-refetch now matches runtypesContract, ioTsContract, zodContract, plus standardSchemaContract (covers any Standard-Schema lib — valibot, arktype, zod 4, …), @withease/contracts (works natively — same Contract shape, no adapter), and createContract. The remaining named gaps are superstruct and typed-contracts (both reachable via Standard Schema where supported).

Where effector-refetch is different (and often nicer)

  • Effect-first. The unit of work is your real Effect (incl. attach factories) — visible in devtools, composable, testable on its own. query.__.effect is exactly what you passed.
  • Friendly config. retry / cache / concurrency / timeout are inline options on createQuery and standalone operators (retry(), cache(), concurrency(), timeout(), keepFresh(), applyBarrier()) — sugar over the same machinery.
  • Real cancellation. createRequestFx gives an AbortSignal; TAKE_LATEST/cancel actually abort the in-flight request, not just discard its result.
  • Declarative HTTP for reads and writes. createJsonQuery + createJsonMutation, both over a reusable request effect (createJsonRequestFx) you can drop into any createQuery.
  • @@trigger both ways. Every query/mutation is a @@trigger (fired = finished.done), so it drives farfetched's keepFresh({ triggers }) — and our keepFresh accepts any @@trigger (withease web-API triggers, farfetched-compatible triggers) or a plain Event in return.
  • Built-in pagination. createInfiniteQuery (bidirectional fetchNext/fetchPrevious, windowing) — farfetched has no built-in equivalent.
  • Built-in offline mode. Both libraries have a createBarrier mutex (e.g. 401 → refresh → replay); effector-refetch adds a ready-made createNetworkBarrier that pauses queries while the browser is offline.
  • Router, structurally. attachToRoute({ route, query }) starts/resets a query on route open/close — without importing atomic-router (any { opened, closed } shape works).
  • Tooling. Visual devtools panels for React, Vue and Solid, an introspection event stream, an llms.txt + a Claude Code agent skill.
  • Bindings & Suspense. useUnit(query) plus useQuery helpers for React / Vue / Solid, and useSuspenseQuery for React Suspense.
  • Small, dependency-free core (~7 kB) under active development toward 1.0.

Side by side

farfetchedeffector-refetch
unit of workinternal event-based executoryour real Effect — first-class
API styleoperatorsinline options and operators
operatorsretry/cache/concurrency/timeout/keepFresh/barriersame set — inline and standalone
sourced configsourced everythingHTTP fields (url/query/body/headers) + curated config
validationruntypes / io-ts / superstruct / typed-contracts / zodruntypes / io-ts / zod / Standard Schema / @withease/contracts (native) / createContract
declarative HTTPcreateJsonQuery + createJsonMutationcreateJsonQuery + createJsonMutation (over createJsonRequestFx)
paginationcreateInfiniteQuery (bidirectional)
cancellationabort + discardreal AbortSignal via createRequestFx
barrier / mutexcreateBarrier + applyBarrier operatorcreateBarrier + applyBarrier operator
offline modebuild it on a barrierbuilt-in createNetworkBarrier
@@trigger protocolimplements + consumes (keepFresh triggers)implements (every query/mutation) + consumes (keepFresh triggers)
router@farfetched/atomic-routerattachToRoute (structural — no router import)
devtools@farfetched/dev-toolsvisual panels (React/Vue/Solid) + introspection stream
bindings@farfetched/solid + useUnitreact / vue / solid + useQuery + useSuspenseQuery
SSRfork / allSettledfork / allSettled
maturity / ecosystemlarger, battle-testedyoung, actively developed

Which should you use?

  • Use farfetched if you want the most mature option today, lean heavily on sourced-everything config, or need the superstruct / typed-contracts validation adapters specifically.
  • Use effector-refetch if you prefer wrapping your own effects, want inline config, real cancellation, built-in pagination, declarative reads and writes, the barrier/offline primitives, structural router integration, cross-framework devtools, or a small core on an actively-maintained project.

Already on farfetched and curious? The migration guide + the npx effector-refetch-codemod tool handle most of the mechanical changes.

MIT Licensed