🧱 Single Responsibility
Each class has one job and does it well. ClientManager handles
connections. Reactor handles canister interactions. DisplayReactor
handles transformations.
In the rapidly evolving landscape of Internet Computer development, choosing the right library is critical. IC Reactor was designed from the ground up with three principles: minimal footprint, type safety, and future-proof architecture.
| Package | Minified + Gzipped | What’s Included |
|---|---|---|
| @ic-reactor/core | ~28 KB | Reactor, caching, transformations, validation |
| @ic-reactor/react | ~2.6 KB | React hooks (excludes core + react) |
That’s it. ~30 KB total for a complete, production-ready data layer.
IC Reactor is designed to be lightweight with only essential peer dependencies:
@ic-reactor/react├── @icp-sdk/core (you already need this for IC development)└── @tanstack/react-query (industry-standard, likely already in your app)IC Reactor’s architecture was built with modern software engineering principles:
🧱 Single Responsibility
Each class has one job and does it well. ClientManager handles
connections. Reactor handles canister interactions. DisplayReactor
handles transformations.
📦 Composition Over Inheritance
Build complex behaviors by composing simple, focused classes. No deep inheritance hierarchies to navigate or debug.
🔌 Dependency Injection
All dependencies are injected, making testing trivial and allowing for custom implementations.
🎯 Zero Lock-in
Use as much or as little as you want. Every component works standalone.
┌─────────────────────────────────────────────────────────────┐│ Your Application │├─────────────────────────────────────────────────────────────┤│ React Layer (@ic-reactor/react) ││ ├── createActorHooks() → useActorQuery, useActorMutation ││ ├── createAuthHooks() → useAuth, useUserPrincipal ││ └── Validation utilities for forms │├─────────────────────────────────────────────────────────────┤│ Core Layer (@ic-reactor/core) ││ ├── ClientManager → Agent + Auth state management ││ ├── Reactor → Canister calls + TanStack caching ││ └── DisplayReactor → Type transformations + validation │├─────────────────────────────────────────────────────────────┤│ SDK Layer (@icp-sdk/core) ││ └── HttpAgent, Principal, IDL, Candid │└─────────────────────────────────────────────────────────────┘| Feature | IC Reactor | DIY (raw SDK) |
|---|---|---|
| Additional Bundle Size | ~30 KB (on top of SDK) | ~50+ KB of custom code |
| Type Safety | ✅ End-to-end from Candid | ⚠️ Manual type assertions |
| Query Caching | ✅ TanStack Query built-in | ❌ Build your own |
| Background Refetch | ✅ Automatic | ❌ Build your own |
| Request Deduplication | ✅ Automatic | ❌ Build your own |
| Optimistic Updates | ✅ First-class support | ❌ Build your own |
| Result Unwrapping | ✅ Ok/Err → try/catch | ❌ Manual unwrapping |
| Error Typing | ✅ CanisterError<E> | ❌ Generic Error |
| Display Transformations | ✅ BigInt→string, Principal→text | ❌ Manual conversion |
| Form Validation | ✅ Zod schemas from Candid | ❌ Build your own |
| Suspense Support | ✅ Built-in | ❌ Complex setup |
| Infinite Queries | ✅ Built-in | ❌ Complex setup |
| DevTools | ✅ TanStack Query DevTools | ❌ None |
| SSR Support | ✅ With prefetching | ⚠️ Tricky |
| Multi-Actor | ✅ Shared ClientManager | ⚠️ Manual coordination |
When you build your own data layer, you’re signing up for:
🧠 AI-Friendly Codebase
LLMs understand IC Reactor. Our consistent patterns, comprehensive JSDoc, and scannable structure means AI assistants can help you write code faster.
📄 /llms.txt Standard
We include /llms.txt in our documentation for structured API overviews
that AI models can parse effectively.
🔮 Predictable Patterns
Every hook, every class follows the same patterns. Once you learn one, you know them all — and so does your AI pair programmer.
📚 Self-Documenting Types
TypeScript types serve as living documentation. Your IDE (and AI) can infer everything from the types alone.
// IC Reactor: AI understands this instantly ✅const { data, isPending, error } = useActorQuery({ functionName: "getBalance", args: [principal],})
// DIY approach: AI struggles with custom abstractions ❌const balance = useCustomHook({ actor: myActor, method: "getBalance", params: [principal], cache: true, retryOnError: 3, transformResult: (r) => extractOk(r),})The first pattern is self-documenting and follows conventions that every AI model trained on TanStack Query will recognize. The second is a custom abstraction that requires context AI doesn’t have.
One of IC Reactor’s most elegant features:
// Your Candid method returns: variant { Ok: nat; Err: text }
const { mutate } = useActorMutation({functionName: "transfer",onSuccess: (balance) => {// balance is typed as `bigint` - Err case throws automatically!console.log(`New balance: ${balance}`);},onCanisterError: (error) => {// error.err is typed as `string`console.error(`Transfer failed: ${error.err}`);},});// Manual approach - tedious and error-proneconst result = await actor.transfer({ to: recipient, amount });
if ("Ok" in result) { console.log(`New balance: ${result.Ok}`);} else if ("Err" in result) { console.error(`Transfer failed: ${result.Err}`);} else { // What if it's lowercase? What if the shape changes? throw new Error("Unexpected result shape");}DisplayReactor automatically converts types for UI consumption:
| Candid Type | Candid Value | Display Value | Automatic? |
|---|---|---|---|
nat / int | 1000000000000n | "1000000000000" | ✅ |
nat64 / int64 | 1234567890123456789n | "1234567890123456789" | ✅ |
principal | Principal.fromText("...") | "aaaaa-aa" | ✅ |
opt T | [value] or [] | value or undefined | ✅ |
blob (≤96 bytes) | Uint8Array | "0x1234..." | ✅ |
variant { Ok; Err } | { Ok: value } | { _type: "Ok", Ok: value } | ✅ |
This means your React components never deal with:
BigInt serialization issues (JSON.stringify fails!)value?.[0])Progressive Enhancement
Start simple, add complexity only when needed. Use Reactor for basic
needs, upgrade to DisplayReactor for forms, add hooks as your React app
grows.
Standards Over Invention
We don’t reinvent the wheel. TanStack Query for caching, Zod for validation, TypeScript for types. Learn once, apply everywhere.
Explicit Over Implicit
No magic. Every transformation, every hook, every option is explicit in your code. Debugging is straightforward because the data flow is visible.
Minimal API Surface
Fewer concepts to learn means faster onboarding. We expose what you need and hide complexity behind sensible defaults.
As the creator and maintainer of IC Reactor, here’s my honest assessment:
Type Safety Is Unmatched — From your .did file to your React components, types flow seamlessly. This catches bugs at compile time, not runtime.
The TanStack Query Foundation — By building on a library with 47K+ GitHub stars and years of battle-testing, we inherit solutions to problems we’d otherwise have to solve ourselves.
Developer Experience — The API is intuitive if you know TanStack Query. If you don’t, you learn a skill that transfers to any React project.
Production Ready — This is v3, not v1. We’ve learned from two major versions, countless production apps, and real user feedback.
Documentation — We’re continuously improving docs with more examples and edge cases. Your feedback helps.
Framework Support — Currently React-focused. Vue, Svelte, and Solid support are on the roadmap.
Offline Support — TanStack Query has offline capabilities we haven’t fully exposed yet.
If you’re building Internet Computer applications in 2026+, there is no reason not to use IC Reactor:
The alternative is spending weeks building what we’ve spent years perfecting.
| Aspect | IC Reactor | DIY Custom Solution |
|---|---|---|
| Learning Curve | ~1 hour if you know TanStack Query | ~2-4 weeks for custom solution |
| Additional Code | ~30 KB (battle-tested) | ~50+ KB (untested custom code) |
| Type Safety | Full end-to-end | Partial, requires manual work |
| Maintenance | Community + maintainer | Your team only |
| Production Apps | Dozens | Depends on your testing |
| AI Assistance | Excellent (familiar patterns) | Poor (custom abstractions) |
| Time to First Feature | Days | Weeks |
| Regret Factor | Low | High |