Quick Start
This tutorial walks you through creating your first IC Reactor integration with React. We’ll use the Vite Plugin to automate declaration generation and hook creation, which is the recommended way to use IC Reactor.
-
Install packages
Section titled “Install packages”Terminal window pnpm add @ic-reactor/react @icp-sdk/core @tanstack/react-querypnpm add -D @ic-reactor/vite-pluginTerminal window npm install @ic-reactor/react @icp-sdk/core @tanstack/react-querynpm install -D @ic-reactor/vite-pluginTerminal window yarn add @ic-reactor/react @icp-sdk/core @tanstack/react-queryyarn add -D @ic-reactor/vite-pluginTerminal window bun add @ic-reactor/react @icp-sdk/core @tanstack/react-querybun add -D @ic-reactor/vite-plugin -
Configure Vite Plugin
Section titled “Configure Vite Plugin”Add the plugin to your
vite.config.ts. This will automatically generate TypeScript declarations and React hooks whenever you modify your.didfile.vite.config.ts import { icReactor } from "@ic-reactor/vite-plugin"export default defineConfig({plugins: [icReactor({canisters: [{name: "backend",didFile: "src/backend/backend.did",},],}),],}) -
Initialize ClientManager
Section titled “Initialize ClientManager”Create a central
ClientManager. The generated reactors will use this by default.src/clients.ts import { ClientManager } from "@ic-reactor/react"import { QueryClient } from "@tanstack/react-query"export const queryClient = new QueryClient()export const clientManager = new ClientManager({ queryClient }) -
Fetch data with Generated Hooks
Section titled “Fetch data with Generated Hooks”Import the generated hooks directly from your declarations folder. They are fully typed and ready to use!
src/components/Greeting.tsx import { useBackendQuery } from "../declarations/backend"function Greeting() {const { data, isPending, error } = useBackendQuery({functionName: "greet",args: ["World"],})if (isPending) return <div>Loading...</div>if (error) return <div>Error: {error.message}</div>return <h1>{data}</h1>} -
Update data with mutations
Section titled “Update data with mutations”Mutations are also generated automatically:
src/components/Counter.tsx import { useBackendQuery, useBackendMutation } from "../declarations/backend"function Counter() {const { data: count } = useBackendQuery({ functionName: "getCount" })const { mutate, isPending } = useBackendMutation({functionName: "increment",onSuccess: () => {// The generated reactor provides helper to invalidate queries// ... custom invalidation logic here},})return (<div><p>Count: {count ?? "..."}</p><button onClick={() => mutate([])} disabled={isPending}>{isPending ? "Incrementing..." : "Increment"}</button></div>)}
Automatic Proxy & Environment
Section titled “Automatic Proxy & Environment”Using the Vite plugin provides several advantages out-of-the-box:
- Zero-config Proxy:
/apirequests are automatically proxied to your local replica. - Auto-Canister IDs: Canister IDs are automatically detected from your local network through
icp-cliwhen environment injection is enabled. - Identity Support: Works seamlessly with local Internet Identity setups.
Canister IDs
Section titled “Canister IDs”In development the plugin injects local canister IDs through the ic_env
cookie, and the generated reactor resolves its own ID from that cookie using the
key PUBLIC_CANISTER_ID:backend.
For production, pin the ID on the canister entry in vite.config.ts. The
generated reactor then emits it directly and no cookie or environment variable
is involved:
icReactor({ canisters: [ { name: "backend", didFile: "src/backend/backend.did", canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai", }, ],})What’s Next?
Section titled “What’s Next?”You now have IC Reactor working! Here’s what to explore next:
- React Setup — Complete configuration with authentication
- Queries — Deep dive into data fetching
- Mutations — Learn about updating data
- Query Caching — Master TanStack Query integration
- Type Safety — Understand the type system