IC Reactor provides seamless integration between your applications and Internet Computer canisters with full TypeScript support, intelligent caching powered by TanStack Query, and first-class React integration.
- π End-to-End Type Safety - From Candid to your components
- β‘ TanStack Query Integration - Automatic caching, background refetching, optimistic updates
- π Auto Transformations - BigInt to string, Principal to text, and more with DisplayReactor
- βοΈ React Ready -
useActorQuery,useActorInfiniteQuery,useActorMutationand more. - π¦ Result Unwrapping - Automatic
Ok/Errhandling from Candid Result types - ποΈ Multi-Actor Support - Manage multiple canisters with shared authentication
- π Internet Identity - Seamless authentication integration
| Package | Description |
|---|---|
@ic-reactor/core |
Core library with ClientManager, Reactor, and query caching |
@ic-reactor/react |
React hooks for seamless integration (re-exports core) |
# For React apps
pnpm add @ic-reactor/react@beta @icp-sdk/core @tanstack/react-query
# For non-React apps
pnpm add @ic-reactor/core@beta @icp-sdk/core @tanstack/query-core
# Optional: Internet Identity authentication
pnpm add @icp-sdk/authimport { ClientManager, Reactor, createActorHooks, createAuthHooks } from '@ic-reactor/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { idlFactory, type _SERVICE } from './declarations/my_canister';
// 1. Setup ClientManager (handles Identity and Agent)
const queryClient = new QueryClient();
const clientManager = new ClientManager({ queryClient, withProcessEnv: true });
// 2. Setup Reactor (handles Canister interaction)
const backend = new Reactor<_SERVICE>({
clientManager,
idlFactory,
canisterId: 'rrkah-fqaaa-aaaaa-aaaaq-cai',
});
// 3. Create Hooks
const { useActorQuery, useActorMutation } = createActorHooks(backend);
const { useAuth, useUserPrincipal } = createAuthHooks(clientManager);
// 4. Use in components
function LoginButton() {
const { login, logout, isAuthenticated, principal } = useAuth();
return isAuthenticated ? (
<button onClick={() => logout()}>Logout {principal?.toText()}</button>
) : (
<button onClick={() => login()}>Login with Internet Identity</button>
);
}
function Greeting() {
const { data, isPending, error } = useActorQuery({
functionName: 'greet',
args: ['World'],
});
if (isPending) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <h1>{data}</h1>;
}| Feature | Standard Actor | Reactor |
|---|---|---|
| Type-safe method calls | β | β |
| Query caching | β | β Built-in |
| Automatic refetching | β | β Background updates |
| Result unwrapping | β Manual | β Automatic |
| Error typing | β Generic | β
CanisterError<E> |
| Identity sharing | β Per-actor | β Via ClientManager |
cd docs
pnpm install
pnpm dev| Example | Description |
|---|---|
| TanStack Router | Full app with routing and authentication |
| Codec Demo | Type transformation demonstrations |
| TypeScript Demo | Pure TypeScript usage |
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Run E2E tests
pnpm test-e2eWe welcome contributions! See CONTRIBUTING.md for guidelines on how to submit PRs, run the project locally, and formatting rules. Please also review our Code of Conduct.
This project is AI-friendly with:
/llms.txtin documentation for structured API overview- Clear, scannable documentation structure
- Complete, copy-pasteable code examples
- Semantic HTML and heading hierarchy
MIT Β© Behrad Deylami