🔒 Type-Safe
End-to-end TypeScript from Candid to components
IC Reactor is often described as the missing data-fetching library for Internet Computer applications, but in more technical terms, it makes fetching, caching, synchronizing and updating canister state in your web applications a breeze.
Most blockchain SDKs do not come with an opinionated way of fetching or updating data in a holistic way. Because of this, developers end up building either meta-frameworks which encapsulate strict opinions about data-fetching, or they invent their own ways of fetching data. This usually means cobbling together component-based state and side-effects, or using more general purpose state management libraries to store and provide asynchronous data throughout their apps.
While most traditional state management libraries are great for working with client state, they are not so great at working with async or server state. This is because canister state is totally different. For starters, canister state:
Once you grasp the nature of canister state in your application, even more challenges will arise as you go, for example:
If you’re not overwhelmed by that list, then that must mean that you’ve probably solved all of your canister state problems already and deserve an award. However, if you are like the vast majority of people, you either have yet to tackle all or most of these challenges — and we’re only scratching the surface!
Rather than reinventing the wheel, IC Reactor is built on top of TanStack Query (formerly React Query) — the industry-standard library for server state management with 47K+ GitHub stars and used by companies like Google, PayPal, Walmart, and Microsoft.
TanStack Query has already solved all the hard problems of server state management:
| Challenge | TanStack Query Solution |
|---|---|
| Caching | Automatic with configurable staleTime and gcTime |
| Request deduplication | Built-in — multiple components requesting same data = 1 network request |
| Background refetching | Automatic on window focus, reconnect, or interval |
| Optimistic updates | First-class support with rollback on failure |
| Pagination / Infinite scroll | useInfiniteQuery with cursor management |
| Retry logic | Configurable retries with exponential backoff |
| Devtools | Chrome extension for debugging cache state |
IC Reactor takes all of this and adds the Internet Computer layer:
.did file to your componentsvariant { Ok: T; Err: E } becomes try/catch with typed errors// IC Reactor gives you TanStack Query powers for IC canistersconst { data, isPending, refetch } = useActorQuery({ functionName: "getBalance", args: [principal], staleTime: 30_000, // TanStack Query option refetchInterval: 60_000, // TanStack Query option})
// Invalidate after mutations — just like TanStack Queryconst { mutate } = useActorMutation({ functionName: "transfer", invalidateQueries: [backend.generateQueryKey({ functionName: "getBalance" })],})In the example below, you can see IC Reactor in its most basic and simple form being used to fetch data from a canister:
import { ClientManager, Reactor } from "@ic-reactor/react"import { createActorHooks } from "@ic-reactor/react"import { QueryClient, QueryClientProvider } from "@tanstack/react-query"import { idlFactory, type _SERVICE } from "./declarations/backend"
// 1. Create the clientconst queryClient = new QueryClient()const clientManager = new ClientManager({ queryClient })
const backend = new Reactor<_SERVICE>({ clientManager, idlFactory, canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",})
// 2. Create hooksconst { useActorQuery, useActorMutation } = createActorHooks(backend)
// 3. Wrap your app in QueryClientProvider (Optional)// Required only if you want to use DevTools or other TanStack Query featuresexport default function App() { return ( <QueryClientProvider client={queryClient}> <Example /> </QueryClientProvider> )}
// 4. Use in your componentsfunction Example() { const { isPending, error, data } = useActorQuery({ functionName: "greet", args: ["World"], })
if (isPending) return "Loading..."
if (error) return "An error has occurred: " + error.message
return ( <div> <h1>{data}</h1> </div> )}This code snippet illustrates the 3 core concepts of IC Reactor:
🔒 Type-Safe
End-to-end TypeScript from Candid to components
⚡ TanStack Query
Industry-standard caching engine with 47K+ GitHub stars
🔄 Auto Transforms
BigInt to string, Principal to text, Result unwrapping
🔐 Auth Built-in
Seamless Internet Identity integration
If you’re new to TanStack Query, these resources will help: