React hooks for RxJS Observables — live state that cooperates with concurrent rendering
RxJS is how you orchestrate the state that plain React makes hard: live streams (chat messages, LLM tokens), time (“posted 5 seconds ago”, intervals, debounce), and data fetching with retry, resume, and cancellation semantics. react-rx is how those streams become React state — with first-class support for Suspense, Transitions, <Activity>, SSR, and the React Compiler.
Why react-rx
- Non-blocking by default.
useObservabledefers store updates: chatty streams can’t make typing feel blocked, and updates coalesce under load. The deferral is identity-coherent — when the observable changes, the previous observable’s value can never render under the new one. - Synchronous emissions paint on the first render. No re-render-on-mount tax: a
BehaviorSubjector replayed value renders immediately, on the client and during SSR. - First-class
<Activity>(React 19.2). Hidden trees keep warm snapshots and reveal instantly; pre-rendered trees start their data fetches during render — see Activity and preload. - Suspense-powered data fetching.
useObservablePromiseturns any observable into ause()-compatible promise: suspend until the first emission, then live-update in place without re-suspending — see Suspense data fetching. - SSR that never throws.
useObservablerenders exactly what the client’s first paint will show. - React Compiler tested. The entire test suite runs twice — once plain, once compiled through the React Compiler.
- Tiny. ESM-only, tree-shakeable, one small dependency, fully typed.
What people build with it
- Streaming LLM replies — tokens accumulate with
scan, several conversations stream concurrently behind<Activity> - “x seconds ago” timestamps — one shared ticking
timerdrives every label, hydration-mismatch-free - Offline-resilient data fetching — polling that pauses offline, resumes on reconnect, retries with backoff
- Render-as-you-fetch tabs — Suspense data fetching with hover preloading
Start with the guide, skim the API reference, or see how react-rx compares to other RxJS bindings and to state libraries like Zustand, XState, and TanStack Query.
Used in production
react-rx powers live document reads, previews, presence, and validation throughout Sanity Studio , the sanity-io/plugins monorepo, and the wider Sanity plugin ecosystem — and direct dependents beyond it, like navikt/aksel .
Agent skill
Working with an AI coding agent? Install the react-rx-best-practices skill from skills.sh — it teaches agents when to use which hook (and when not to), how to keep observables referentially stable, and how to refactor hand-rolled useEffect + .subscribe() bridges:
npx skills add sanity-io/react-rx --skill react-rx-best-practicesAgents can also read these docs as a single markdown file at react-rx.dev/llms-full.txt .
