@ic-reactor/react
@ic-reactor/react is the recommended package for React applications. It
re-exports the runtime classes from @ic-reactor/core and
adds hook factories, auth hooks, direct reactor hooks, and reusable query
factories designed around TanStack Query.
Why Use This Package
Section titled “Why Use This Package”- You want idiomatic React hooks for queries, mutations, suspense, and auth.
- You want
ClientManager,Reactor, andDisplayReactorfrom one package, in client components and in React Server Components alike (a server component resolves the package’s hook-freereact-serverentry; see Server-Side Rendering). - You want to keep your app code focused on components instead of manual query wiring.
Installation
Section titled “Installation”pnpm add @ic-reactor/react @tanstack/react-query @icp-sdk/core
# Optional: Internet Identity support (@icp-sdk/auth v8)pnpm add @icp-sdk/authreact is the only required React peer — react-dom is declared as an
optional peer and never imported. @icp-sdk/auth is optional too: it is
loaded through a literal import("@icp-sdk/auth/client") inside a try
block, which webpack-family bundlers treat as declaring an optional
dependency — with the peer absent the build succeeds and prints one
Module not found: Can't resolve '@icp-sdk/auth/client' warning. Install the
peer to remove the warning, or silence it with
ignoreWarnings
(in Next.js, assign it inside the webpack(config) callback):
ignoreWarnings: [{ module: /@ic-reactor\/react/, message: /@icp-sdk\/auth/ }]That optional-try treatment is webpack-specific — other bundlers may fail to
resolve the missing specifier at build time. If yours does, install the peer,
or construct the AuthClient yourself and pass it as authClient to
AuthenticationManager, in which case IC Reactor never imports
@icp-sdk/auth at all.
The package requires Node.js 18+ (declared in engines).
What’s Included
Section titled “What’s Included”Quick Start
Section titled “Quick Start”import { ClientManager, Reactor, createActorHooks } from "@ic-reactor/react"import { QueryClient } from "@tanstack/react-query"import { canisterId, idlFactory, type _SERVICE } from "./declarations/backend"
const queryClient = new QueryClient()export const clientManager = new ClientManager({ queryClient })
export const backend = new Reactor<_SERVICE>({ clientManager, idlFactory, name: "backend", // Required unless the Vite plugin injects an `ic_env` cookie for this // canister on a local replica. Without it the reactor constructor throws // on a server and on any deployed origin. canisterId,})
export const { useActorQuery, useActorMutation } = createActorHooks(backend)Bundle Size
Section titled “Bundle Size”What each setup path adds to a browser bundle, measured with esbuild 0.28
(minified ESM, @ic-reactor/core bundled). The peers react,
@tanstack/react-query and @icp-sdk/* are left out, since an app ships them
either way; so is @icp-sdk/auth, which loads as its own chunk on first use.
| Setup | Minified | Gzipped | zod |
|---|---|---|---|
createActorHooks + Reactor + ClientManager |
31 kB | 9.8 kB | no |
… + AuthenticationManager + createAuthHooks |
52 kB | 14.9 kB | no |
… + IdentityAttributesManager + createIdentityAttributeHooks |
58 kB | 16.7 kB | no |
createActorHooks + DisplayReactor + ClientManager |
129 kB | 37.3 kB | yes |
defineDisplayReactor |
158 kB | 45.4 kB | yes |
defineReactor |
158 kB | 45.4 kB | yes |
DisplayReactor builds its codecs on zod’s classic API, which does not
tree-shake. That is about 85 kB minified (24 kB gzipped) of every row marked
“yes”; an app that already bundles zod for its own code pays it once.
defineReactor costs as much as defineDisplayReactor today, even without
display: its deprecated display: true option can still build a
DisplayReactor, so the class and zod stay in the bundle. When that option is
removed at the next major, defineReactor drops to about 60 kB minified,
17.6 kB gzipped. Until then, an app that wants the smallest bundle and has no
use for DisplayReactor sets up with createActorHooks(new Reactor(...)) (the
Quick Start above) and
createAuthHooks.
Both define* functions also include the identity-attribute code (about 6 kB
minified, 1.8 kB gzipped) whether or not the app calls useIdentityAttributes,
because it is part of the object they return.
Identity Attributes
Section titled “Identity Attributes”useIdentityAttributes() comes from createIdentityAttributeHooks(), a factory
separate from createAuthHooks(). It returns the helpers for requesting signed
OpenID email and profile attributes:
import { AuthenticationManager, IdentityAttributesManager, createIdentityAttributeHooks,} from "@ic-reactor/react"// The `clientManager` and `backend` the Quick Start's module exportsimport { backend, clientManager } from "./reactor"
const authentication = new AuthenticationManager({ clientManager })const identityAttributes = new IdentityAttributesManager(authentication)
const { useIdentityAttributes } = createIdentityAttributeHooks(identityAttributes)
function ContinueWithProvider() { const { requestOpenIdAttributes, isRequestingAttributes } = useIdentityAttributes()
async function handleClick() { const result = await requestOpenIdAttributes({ // Pass the nonce as a callback: awaiting it first ends the user gesture // and the browser blocks the Internet Identity window. nonce: () => backend.callMethod({ functionName: "register_begin" }), openIdProvider: "microsoft", keys: ["email", "name"], })
await backend.callMethod({ functionName: "register_finish", args: [ { data: result.signedAttributes.data, signature: result.signedAttributes.signature, }, ], }) }
return ( <button disabled={isRequestingAttributes} onClick={handleClick}> Continue with provider </button> )}Provider aliases ("google", "apple", and "microsoft") and full issuer URLs
are supported. Always verify the signed payload server-side or in your canister
before trusting decoded values.
See Also
Section titled “See Also”- Queries — Standard query patterns
- Mutations — Update and invalidation patterns
- Authentication — Internet Identity and identity attributes
- Query Caching — Cache behavior and invalidation
- Testing — Component and hook tests against a fake
replica, with
@ic-reactor/react/testing - @ic-reactor/core — Runtime layer re-exported by this package