Skip to content
IC Reactor

@ic-reactor/codegen

@ic-reactor/codegen contains the shared generation pipeline used by @ic-reactor/cli and @ic-reactor/vite-plugin. It is the advanced, programmatic entry point for generating declarations, reactor files, and client boilerplate from Candid definitions.

Terminal window
pnpm add -D @ic-reactor/codegen

The primary API is runCanisterPipeline, which coordinates parsing, naming, declaration generation, and reactor file generation.

import { runCanisterPipeline } from "@ic-reactor/codegen"
await runCanisterPipeline({
canisterConfig: {
name: "backend",
didFile: "./backend/backend.did",
mode: "DisplayReactor",
},
projectRoot: process.cwd(),
globalConfig: {
outDir: "src/declarations",
clientManagerPath: "../../clients",
target: "react",
},
})
  • runCanisterPipeline for full end-to-end generation.
  • Naming helpers like toPascalCase, getReactorName, and getServiceTypeName.
  • Lower-level generators when you need declarations, reactor files, or client files separately.

For each canister, the pipeline writes into <outDir>/<name>/:

  • declarations/<did-basename>.js: the IDL factory module
  • declarations/<did-basename>.d.ts: the TypeScript service types
  • declarations/<did-basename>.did: a copy of the source .did
  • index.generated.ts: managed implementation, always regenerated
  • index.ts: stable entry wrapper, preserved unless it still matches the default wrapper or an older generated scaffold that can be migrated — a migrated file is copied to index.ts.bak first, and one carrying any export the old generator never wrote is left alone

The declaration filenames come from the .did file’s basename, not the canister name. The whole declarations/ directory is recreated on every run, but the new files are staged first and swapped in only once all of them are written, so a .did that fails to parse leaves the previous declarations in place instead of deleting them. With target: "react", index.generated.ts also exports the hooks bound to the generated reactor — use<Pascal>Query, use<Pascal>SuspenseQuery, use<Pascal>InfiniteQuery, use<Pascal>SuspenseInfiniteQuery, use<Pascal>Mutation, and use<Pascal>Method. No createQuery or createMutation objects are generated; for use outside React, call the generated reactor’s fetchQuery() / callMethod() / invalidateQueries() directly.

Generated output can target any of these reactor classes:

  • DisplayReactor
  • Reactor
  • CandidReactor
  • CandidDisplayReactor
  • MetadataDisplayReactor

The three Candid modes always import from @ic-reactor/candid, regardless of runtime target, so that package must be installed when you pick one. Only Reactor and DisplayReactor switch import source based on the target.

  • react (default): generates the reactor plus bound React hooks
  • core: generates only the typed reactor exports with no React dependency