# Guide: Building ChainRender Apps with AI

ChainRender was **designed to be built with AI.** Its SDK is headless, AST-first, and exposes a machine-readable
vocabulary — which means an AI assistant can compose, grade, and verify a ChainRender app, and you can *check* the
result rather than trust it. This guide shows how to build with an AI assistant today, step by step.

> **Why ChainRender is well-suited to AI:** the vocabulary is *closed* (an AI can't hallucinate an invalid
> construct — it's constrained by the schema), every app is *graded* (the AI's output has a verifiable trust
> letter), and everything *compiles deterministically* (the same input always yields the same hash). AI output on
> ChainRender is checkable, not blind.

## Step 1 — Give the AI the vocabulary

The single most important step: give the AI the **machine-readable vocabulary** so it composes only valid
constructs. Call `vocabulary()` and provide its output as context:

```ts
import { vocabulary } from "@chainrender/client";

const schema = vocabulary();
// schema.nodeTypes     — every UI primitive (box, text, button, chart, …)
// schema.capabilities  — the capability bits (READ_CHAIN, WRITE_CHAIN, VALUE, …)
// schema.resolverKinds — the on-chain data sources it can bind to
```

Paste `JSON.stringify(vocabulary())` into your AI's context (a system prompt, a tool result, or a pasted block).
Now the AI knows *exactly* what it can and can't express — it composes within the closed vocabulary instead of
guessing at an API.

The full vocabulary is ~59 KB, most of it the resolver-kind list. If context is tight, give the AI everything except
`resolverKinds` and let it look kinds up (the MCP server's `chainrender_search_kinds` / `chainrender_describe_kind`,
or **[All Resolver Kinds](../reference/resolver-kinds.md)**). For the rules in prose, point it at
`https://chainrender.org/docs/llms.txt` — the docs as Markdown, one line per page.

## Step 2 — Describe what you want

With the vocabulary in context, describe your app in plain English:

> "Make me an NFT gallery: a heading, a grid of on-chain NFT images bound to the NftImage resolver, and a Grade-A
> footer. No off-chain assets."

The AI composes it using `compose.*` builders from the vocabulary.

## Step 3 — Check the tree

`compile()` silently drops anything it doesn't read — an unknown field, an enum value that isn't in the list (a
`role: "note"`, a `direction: "vertical"`), a11y fields on an image, `args` on a batch member. The tree compiles and
the component ships without what the AI wrote. Check it first and have the AI fix every issue:

```ts
import { checkNode } from "@chainrender/client";   // 0.10.0+
const r = checkNode(app);   // { ok, issues: [{ path, code, message }] }
```

The same rules are available as a strict JSON Schema (`nodeJsonSchema()`), for tooling that can constrain an AI's
output with one. Every field is listed on **[Node Fields](../reference/node-fields.md)**.

## Step 4 — Have the AI grade it (and iterate on trust)

Ask the AI to grade its own output before you accept it:

```ts
import { grade } from "@chainrender/client";
const g = grade(app);   // "A" / "B" / "C" + itemized breakdown
```

This is the key AI-safety loop: **the grade is verifiable.** If the AI produced a Grade-C app (an off-chain
dependency slipped in), the breakdown names it — you (or the AI) fix it and re-grade. The AI can't *claim*
trustlessness it doesn't have; the grade is computed, not asserted.

## Step 5 — Compile and check the hash

```ts
import { compileComponent } from "@chainrender/client";
const built = compileComponent(app);   // deterministic content-addressed hash
```

Compilation is deterministic, so you can reproduce the AI's exact output and verify the hash independently. What
the AI made is exactly what you'll deploy — no hidden divergence.

## Step 6 — Validate before deploying

Run the same validation the on-chain enforcer runs. If the AI composed something that would be *refused* on-chain,
it fails here first, locally, in milliseconds — so you never deploy an invalid app the AI hallucinated.

## The whole AI loop

```
give vocabulary → describe in English → AI composes → check (nothing dropped) → grade (verify trust) → compile (verify hash) → validate → deploy
```

Every step after "AI composes" is a **check**, not blind trust. That's what makes AI-built ChainRender apps safe:
the output is constrained (closed vocabulary), graded (verifiable trust), deterministic (reproducible hash), and
enforced (refused if unsafe).

## Two ways to use AI

- **Any AI assistant, today:** paste `vocabulary()` into context and use the loop above — `vocabulary()`, `grade()`,
  `compileComponent()`, and validation are all shipped in `@chainrender/client`.
- **Via the MCP server (`@chainrender/mcp`):** for an AI in an MCP-capable editor or chat, the **ChainRender MCP
  server** exposes the SDK as tools (`chainrender_vocabulary`, `chainrender_search_kinds`,
  `chainrender_describe_kind`, `chainrender_check_node`, `chainrender_grade`, `chainrender_compile`,
  `chainrender_validate`, `chainrender_review`) so the AI calls them directly — no pasting. See
  **[MCP Server & AI Skill](../reference/mcp-and-skill.md)**.
- **With the ChainRender skill:** the `chainrender-app-builder` **skill** packages the workflow, rules, and worked
  examples for an AI agent to load, so it builds correctly without hand-holding.

Still on the roadmap: an interactive **[visual builder & playground](../resources/visual-builder.md)** — a graphical canvas on the same foundation.

If the AI also writes Solidity (a custom resolver or app contract), give it the toolchain settings in
**[Local Build Environment](./local-build-environment.md)** — Hardhat 3, solc 0.8.36, `cancun`, optimizer 200 with
`yul: false`, no viaIR — and what to do about the `npm audit` Zod advisory.

## Related
- **[Instructing an AI: Prompt Patterns](../reference/instructing-ai.md)** — how to phrase instructions for good results.
- **[The Vocabulary](../reference/vocabulary.md)** — what `vocabulary()` exposes.
- **[Build, Grade & Style Before Deploy](./test-before-deploy.md)** — the verification loop the AI plugs into.


## Choosing a model

Each AI provider (OpenAI, Anthropic/Claude, Google Gemini, Ollama) offers a **model-quality dropdown** with current
options labelled by speed/quality (e.g. a fast default and a flagship), plus a **Custom** entry to type any model id
-- because model line-ups change often. Set your API key per provider; keys are session-only and never persisted.

## Fixing errors with AI

When a generated rich-media sketch errors (e.g. a black canvas, or `THREE is not defined`), the builder captures the
error and offers **"Fix with AI"** -- it re-prompts the model with the error plus the broken sketch and asks for a
corrected version, then re-runs the preview. It iterates: if the fix still errors, click again. Build/validation
failures get the same treatment (the error is appended to the prompt on regenerate).

## Start from working code, not from scratch

The most reliable way to a correct on-chain app is to clone a known-good shape: run `npm create chainrender@latest` (its template already uses `renderComponent`), or copy the app-builder skill's `examples/correct-react-app.tsx`. Building a React app from scratch tends to drift into a viem dashboard that only prints a content hash — start from the reference and keep its compile→register→render loop intact. See [Building Correctly](../concepts/building-correctly.md).
