{"id":35511835,"url":"https://github.com/b3pay/ic-reactor","last_synced_at":"2026-03-13T10:05:25.219Z","repository":{"id":210965869,"uuid":"727869559","full_name":"B3Pay/ic-reactor","owner":"B3Pay","description":"IC-Reactor: A suite of JavaScript libraries for seamless frontend development on the Internet Computer platform, offering state management, React integration, and core functionalities for efficient blockchain interactions.","archived":false,"fork":false,"pushed_at":"2026-02-05T22:06:56.000Z","size":53022,"stargazers_count":18,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-05T22:22:17.102Z","etag":null,"topics":["dfinity","hooks","icp","internet-computer-protocol","internet-identity","reactjs","typescript"],"latest_commit_sha":null,"homepage":"https://b3pay.github.io/ic-reactor/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/B3Pay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-05T18:39:29.000Z","updated_at":"2026-02-05T22:06:56.000Z","dependencies_parsed_at":"2026-02-05T13:05:45.405Z","dependency_job_id":null,"html_url":"https://github.com/B3Pay/ic-reactor","commit_stats":null,"previous_names":["b3hr4d/ic-reactor"],"tags_count":514,"template":false,"template_full_name":null,"purl":"pkg:github/B3Pay/ic-reactor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B3Pay%2Fic-reactor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B3Pay%2Fic-reactor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B3Pay%2Fic-reactor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B3Pay%2Fic-reactor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/B3Pay","download_url":"https://codeload.github.com/B3Pay/ic-reactor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/B3Pay%2Fic-reactor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29451873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T15:52:44.973Z","status":"ssl_error","status_checked_at":"2026-02-14T15:52:11.208Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dfinity","hooks","icp","internet-computer-protocol","internet-identity","reactjs","typescript"],"created_at":"2026-01-03T21:15:29.995Z","updated_at":"2026-03-13T10:05:25.201Z","avatar_url":"https://github.com/B3Pay.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IC Reactor\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"docs/src/assets/icon.svg\" alt=\"IC Reactor Logo\" width=\"240\" /\u003e\n  \u003cbr\u003e\u003cbr\u003e\n  \u003cstrong\u003eType-safe Internet Computer integration for TypeScript and React\u003c/strong\u003e\n  \u003cbr\u003e\u003cbr\u003e\n\n[![npm version](https://img.shields.io/npm/v/@ic-reactor/core.svg)](https://www.npmjs.com/package/@ic-reactor/core)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)\n\n\u003c/div\u003e\n\n---\n\nIC Reactor is a monorepo of libraries for building Internet Computer (ICP) apps with:\n\n- end-to-end TypeScript types\n- TanStack Query-powered caching and refetching\n- React hook factories (`useActorQuery`, `useActorMutation`, etc.)\n- display-friendly transforms (`DisplayReactor`)\n- optional code generation (CLI + Vite plugin)\n\n## Why IC Reactor\n\nIC Reactor gives you a higher-level API than raw `Actor` usage while keeping type safety and control:\n\n- typed canister method calls\n- built-in cache keys and invalidation primitives\n- typed `Ok`/`Err` result handling\n- shared auth/agent management via `ClientManager`\n- reusable query/mutation objects that work both inside and outside React\n\n## Package Overview\n\n| Package                                             | Purpose                                                                        |\n| --------------------------------------------------- | ------------------------------------------------------------------------------ |\n| [`@ic-reactor/core`](./packages/core)               | Core runtime (`ClientManager`, `Reactor`, `DisplayReactor`, cache integration) |\n| [`@ic-reactor/react`](./packages/react)             | React hooks + query/mutation factories                                         |\n| [`@ic-reactor/candid`](./packages/candid)           | Dynamic Candid parsing and runtime reactors                                    |\n| [`@ic-reactor/parser`](./packages/parser)           | Local Candid parser (WASM-based)                                               |\n| [`@ic-reactor/codegen`](./packages/codegen)         | Shared codegen pipeline used by CLI and Vite plugin                            |\n| [`@ic-reactor/cli`](./packages/cli)                 | Generate declarations + typed hooks/reactors                                   |\n| [`@ic-reactor/vite-plugin`](./packages/vite-plugin) | Vite plugin for watch-mode hook generation                                     |\n\n## Install\n\n### React apps\n\n```bash\npnpm add @ic-reactor/react @icp-sdk/core @tanstack/react-query\n```\n\n### Non-React apps\n\n```bash\npnpm add @ic-reactor/core @icp-sdk/core @tanstack/query-core\n```\n\n### Optional packages\n\n```bash\n# Internet Identity auth helpers\npnpm add @icp-sdk/auth\n\n# Dynamic Candid support (explorers/dev tools)\npnpm add @ic-reactor/candid @ic-reactor/parser\n```\n\n## Quick Start (React)\n\n### 1. Create a shared client manager and reactor\n\n```ts\n// src/reactor.ts\nimport { ClientManager, Reactor } from \"@ic-reactor/react\"\nimport { QueryClient } from \"@tanstack/react-query\"\nimport { idlFactory, type _SERVICE } from \"./declarations/my_canister\"\n\nexport const queryClient = new QueryClient()\n\nexport const clientManager = new ClientManager({\n  queryClient,\n  // withCanisterEnv: true, // optional: useful in local/dev setups\n})\n\nexport const backendReactor = new Reactor\u003c_SERVICE\u003e({\n  clientManager,\n  idlFactory,\n  name: \"backend\",\n  canisterId: \"rrkah-fqaaa-aaaaa-aaaaq-cai\",\n})\n```\n\n### 2. Create hooks\n\n```ts\n// src/hooks.ts\nimport { createActorHooks, createAuthHooks } from \"@ic-reactor/react\"\nimport { backendReactor, clientManager } from \"./reactor\"\n\nexport const {\n  useActorQuery,\n  useActorMutation,\n  useActorSuspenseQuery,\n  useActorInfiniteQuery,\n} = createActorHooks(backendReactor)\n\nexport const { useAuth, useUserPrincipal } = createAuthHooks(clientManager)\n```\n\n### 3. Use in React components\n\n```tsx\n// src/App.tsx\nimport { QueryClientProvider } from \"@tanstack/react-query\"\nimport { queryClient } from \"./reactor\"\nimport { useActorQuery, useActorMutation, useAuth } from \"./hooks\"\n\nfunction Greeting() {\n  const { data, isPending, error } = useActorQuery({\n    functionName: \"greet\",\n    args: [\"World\"],\n  })\n\n  if (isPending) return \u003cdiv\u003eLoading...\u003c/div\u003e\n  if (error) return \u003cdiv\u003eError: {error.message}\u003c/div\u003e\n\n  return \u003ch1\u003e{data}\u003c/h1\u003e\n}\n\nfunction AuthButton() {\n  const { login, logout, isAuthenticated, principal } = useAuth()\n\n  return isAuthenticated ? (\n    \u003cbutton onClick={() =\u003e logout()}\u003e\n      Logout {principal?.toText().slice(0, 8)}...\n    \u003c/button\u003e\n  ) : (\n    \u003cbutton onClick={() =\u003e login()}\u003eLogin\u003c/button\u003e\n  )\n}\n\nfunction UpdateProfileButton() {\n  const { mutate, isPending } = useActorMutation({\n    functionName: \"update_profile\",\n  })\n\n  return (\n    \u003cbutton\n      disabled={isPending}\n      onClick={() =\u003e mutate([{ name: \"Alice\", bio: \"Hello IC\" }])}\n    \u003e\n      {isPending ? \"Saving...\" : \"Save\"}\n    \u003c/button\u003e\n  )\n}\n\nexport function App() {\n  return (\n    \u003cQueryClientProvider client={queryClient}\u003e\n      \u003cAuthButton /\u003e\n      \u003cGreeting /\u003e\n      \u003cUpdateProfileButton /\u003e\n    \u003c/QueryClientProvider\u003e\n  )\n}\n```\n\n## Core Usage Patterns\n\n### Pattern A: Generic hooks with `createActorHooks(...)`\n\nUse when component code can pass `functionName` and `args` inline.\n\n- Best for straightforward React integration\n- Single typed hook suite per reactor\n\n### Pattern B: Reusable query/mutation factories (recommended for shared use)\n\nUse when the same operation must be used:\n\n- inside React components\n- in route loaders/actions\n- in services or test helpers\n\n```ts\nimport { createQuery, createMutation } from \"@ic-reactor/react\"\nimport { backendReactor } from \"./reactor\"\n\nexport const getProfile = createQuery(backendReactor, {\n  functionName: \"get_profile\",\n})\n\nexport const updateProfile = createMutation(backendReactor, {\n  functionName: \"update_profile\",\n  invalidateQueries: [getProfile.getQueryKey()],\n})\n```\n\nInside React:\n\n```tsx\nconst { data } = getProfile.useQuery()\nconst { mutateAsync } = updateProfile.useMutation({\n  onSettled: () =\u003e toast.success(\"Profile updated!\"),\n})\n```\n\nOutside React:\n\n```ts\nawait getProfile.fetch()\nconst cached = getProfile.getCacheData()\nawait updateProfile.execute([{ name: \"Alice\" }])\n```\n\nImportant: Do not call React hooks (`useActorQuery`, `.useQuery()`, `.useMutation()`) outside React components or custom hooks.\n\n### Pattern C: `DisplayReactor` for UI-friendly values\n\nUse `DisplayReactor` when you want transformed values for UI/forms (for example, `bigint` and `Principal` represented as strings).\n\n```ts\nimport { DisplayReactor } from \"@ic-reactor/react\"\n```\n\n## Code Generation (CLI and Vite Plugin)\n\nFor larger canisters or frequent `.did` changes, prefer generated hooks.\n\n### Vite plugin (recommended for Vite apps)\n\n```ts\n// vite.config.ts\nimport { defineConfig } from \"vite\"\nimport react from \"@vitejs/plugin-react\"\nimport { icReactor } from \"@ic-reactor/vite-plugin\"\n\nexport default defineConfig({\n  plugins: [\n    react(),\n    icReactor({\n      canisters: [{ name: \"backend\", didFile: \"./backend/backend.did\" }],\n    }),\n  ],\n})\n```\n\n### CLI (explicit generation / non-Vite)\n\n```bash\nnpx @ic-reactor/cli init\nnpx @ic-reactor/cli generate\n```\n\nGenerated query/mutation files typically expose both:\n\n- React methods (`.useQuery()`, `.useMutation()`)\n- imperative methods (`.fetch()`, `.execute()`, `.invalidate()`)\n\n## Dynamic Candid (Explorers and Dev Tools)\n\n```ts\nimport { CandidDisplayReactor } from \"@ic-reactor/candid\"\nimport { ClientManager } from \"@ic-reactor/core\"\n\nconst clientManager = new ClientManager()\n\nconst reactor = new CandidDisplayReactor({\n  canisterId: \"ryjl3-tyaaa-aaaaa-aaaba-cai\",\n  clientManager,\n})\n\nawait reactor.initialize()\n\nconst balance = await reactor.callMethod({\n  functionName: \"icrc1_balance_of\",\n  args: [{ owner: \"aaaaa-aa\" }],\n})\n\nconsole.log(balance)\n```\n\n## Reactor vs Standard Actor (Summary)\n\n| Feature                                   | Standard Actor | IC Reactor            |\n| ----------------------------------------- | -------------- | --------------------- |\n| Type-safe method calls                    | ✅             | ✅                    |\n| Query caching                             | ❌             | ✅                    |\n| Background refetching                     | ❌             | ✅                    |\n| Typed `Ok`/`Err` handling                 | ❌ (manual)    | ✅                    |\n| Shared auth/identity + cache coordination | ❌             | ✅ (`ClientManager`)  |\n| Display-friendly transforms               | ❌             | ✅ (`DisplayReactor`) |\n\n## Examples\n\n| Example                                             | Description                                                         |\n| --------------------------------------------------- | ------------------------------------------------------------------- |\n| [`all-in-one-demo`](./examples/all-in-one-demo)     | End-to-end demo with queries, mutations, suspense, infinite queries |\n| [`tanstack-router`](./examples/tanstack-router)     | Router loaders/actions + generated hooks                            |\n| [`query-demo`](./examples/query-demo)               | Query and mutation factory patterns                                 |\n| [`multiple-canister`](./examples/multiple-canister) | Shared auth across multiple canisters                               |\n| [`ckbtc-wallet`](./examples/ckbtc-wallet)           | More advanced canister integrations                                 |\n| [`codegen-in-action`](./examples/codegen-in-action) | CLI vs Vite plugin codegen comparison                               |\n| [`typescript-demo`](./examples/typescript-demo)     | Core usage without React                                            |\n| [`candid-parser`](./examples/candid-parser)         | Dynamic Candid parsing                                              |\n\n## Documentation\n\n- Docs site source: [`./docs`](./docs)\n- Package docs:\n  - [`@ic-reactor/react`](./packages/react/README.md)\n  - [`@ic-reactor/core`](./packages/core/README.md)\n  - [`@ic-reactor/candid`](./packages/candid/README.md)\n  - [`@ic-reactor/cli`](./packages/cli/README.md)\n  - [`@ic-reactor/vite-plugin`](./packages/vite-plugin/README.md)\n\nRun docs locally:\n\n```bash\ncd docs\npnpm install\npnpm dev\n```\n\n## Development\n\n```bash\n# Install dependencies\npnpm install\n\n# Build packages\npnpm build\n\n# Run package tests\npnpm test\n\n# Run e2e tests\npnpm test-e2e\n\n# Build docs\npnpm docs:build\n```\n\n## AI and Agent Integration\n\nThis repository is intentionally structured to work well with AI coding assistants and agents.\n\n### AI context files\n\n- [`./llms.txt`](./llms.txt) — high-level library context for LLMs\n- [`B3Pay/ic-reactor-skills`](https://github.com/B3Pay/ic-reactor-skills) — installable IC Reactor skills mono-repo\n- [`./.cursorrules`](./.cursorrules) — Cursor-specific behavior guidance\n\n### Installable Skill: `ic-reactor-hooks`\n\nThe canonical installable IC Reactor hooks skill lives in the skills mono-repo:\n\n- repo: [`B3Pay/ic-reactor-skills`](https://github.com/B3Pay/ic-reactor-skills)\n- skill path: `ic-reactor-hooks`\n\nUse it when asking an agent to:\n\n- create/refactor `createActorHooks(...)` integrations\n- build reusable `createQuery` / `createMutation` modules\n- explain inside-React vs outside-React usage (`fetch`, `execute`, `invalidate`)\n- choose between manual hooks and generated hooks (CLI / Vite plugin)\n\nExample prompt:\n\n```text\nUse $ic-reactor-hooks to create a reusable query/mutation factory pair for my canister and show usage both inside a React component and in a route loader.\n```\n\nExample install:\n\n```bash\nnpx skills add B3Pay/ic-reactor-skills --full-depth --skill ic-reactor-hooks\n```\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](./CONTRIBUTING.md) for development workflow, formatting, release notes, and AI-assisted contribution guidance.\n\nPlease also review the [Code of Conduct](./CODE_OF_CONDUCT.md).\n\n## License\n\nMIT © [Behrad Deylami](https://github.com/b3hr4d)\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  Built for the \u003ca href=\"https://internetcomputer.org\"\u003eInternet Computer\u003c/a\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb3pay%2Fic-reactor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fb3pay%2Fic-reactor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb3pay%2Fic-reactor/lists"}