candid-to-zod
v1.0.2
Published
Convert Internet Computer Candid files (.did.js, .did.ts) into runtime-safe TypeScript Zod validation schemas.
Downloads
358
Maintainers
Readme
candid-to-zod ⚡️
candid-to-zod is a powerful Node.js CLI tool and isomorphic library for the Internet Computer that instantly converts exported Candid types (.did.js, .did.ts) into runtime-safe TypeScript Zod Schemas.
Stop guessing what data structures your Canisters return! Guarantee end-to-end type safety across the IC boundary by ensuring your frontend strictly parses incoming canister data against robust Zod definitions.
🚀 Features
- CLI Generation: Automatically compile Zod schemas natively in your terminal or CI/CD pipelines.
.ts&.jsSupport: Seamlessly analyzesdfxoutput files (e.g.export const init = ...).- Deep Types & Variants: Recursively maps nested Candid Vectors, Records, Options, and complex disjoint Variants into
z.array,z.object,z.optional, andz.union. - Inferred Types: Automatically generates
z.infer<>TypeScript types alongside your schemas.
🤔 Why do I need this? (Zod vs dfx Types)
If you're building on the Internet Computer, you're likely using the default TypeScript declarations generated by dfx generate.
However, TypeScript is only a static compile-time tool. It does not exist at runtime!
If a canister is upgraded, if an API changes, or if an unexpected payload is returned from the blockchain, standard TypeScript will not block the corrupted data from entering your frontend app state—it will blindly assume the data matches the interface.
candid-to-zod solves this. By converting your Candid files into Zod schemas, you guarantee end-to-end runtime type safety. When you call zodSchema.parse(response), Zod actively strips unknown keys, verifies all required fields exist, and immediately throws a safe error if the blockchain data doesn't perfectly match your definitions!
📦 Installation
Install as a development dependency in your project:
npm install -D candid-to-zodYou'll also need the core Zod and Dfinity packages installed:
npm install zod @dfinity/principal @dfinity/candid💻 Usage
1. Generate Schema via CLI
Add a script to your project's package.json to automatically build your schemas after running dfx generate:
{
"scripts": {
"generate:zod": "candid-to-zod -i ./src/declarations/my_canister/my_canister.did.js -o ./src/schemas/my_canister.ts"
}
}Then run:
npm run generate:zodCLI Options
| Flag | Name | Description | default |
|---|---|---|---|
| -i, --input | Input Path | The generated .did.js or .did.ts Candid file | Required |
| -o, --output | Output Path| Where to save the formatted .ts Zod schema | Required |
| --no-infer | Skip Inferences | Skip generating export type X = z.infer<typeof XSchema>; | false |
[!TIP] Flexible Export Discovery: The CLI automatically detects your IDL factory even if it's not named
idlFactory. It looks for any export ending inIdlFactory, making it compatible with all versions ofdfx generate.
2. Validate Data in your App
Once your schemas have been generated, import them to rigorously type-check your Web3 requests!
import { my_canister } from "../declarations/my_canister";
import { getUserRetSchema } from "../schemas/my_canister.ts";
// 1. Fetch from your Canister
const rawResponse = await my_canister.getUser(principal);
// 2. Parse using Zod
// Strips unknown keys, guarantees runtime presence, and infers TypeScript return types natively!
const safeUser = getUserRetSchema.parse(rawResponse);
console.log(`Verified username: ${safeUser.username}`);🏗 Using the Generator Programmatically (Library Mode)
You can also bypass the CLI and pass raw idlFactory objects directly to the generator function within the browser or Node:
import { generateZod } from "candid-to-zod";
import { idlFactory } from "./my_canister.did.js";
// Generates the Zod code as a string!
const stringifiedZodCode = generateZod(idlFactory, { inferTypes: true });
console.log(stringifiedZodCode);🤝 Contributing
Built and maintained by Ibnyahyah. PRs and feature requests are welcome!
💖 Support the project: If you find this tool helpful, consider supporting the development at socio.kim/donate.
