React hooks for RxJS Observables. Live state that works with concurrent rendering.
RxJS is great at the state that plain React makes hard:
- Live streams: chat messages, LLM tokens, sockets, presence
- Time: timers, intervals, debounce, “posted 5 seconds ago”
- Data fetching with retry, resume, and cancellation
react-rx turns those streams into React state. It has 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. Updates coalesce under load. - Identity-coherent deferral. When the observable changes, the previous observable’s value can never render under the new one.
- Synchronous emissions paint on the first render. A
BehaviorSubjector replayed value renders immediately. No re-render-on-mount tax. Works during SSR too. - 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. 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 at once behind<Activity> - “x seconds ago” timestamps: one shared
timerdrives every label, with no hydration mismatches - 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 . It is also used across the sanity-io/plugins monorepo, 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 .
