# 🎯 How json-render Works in This Demo
## The Flow
```
User Prompt (in production)
↓
AI generates JSON spec (constrained to catalog)
↓
json-render Renderer component
↓
Beautiful React UI
```
## Step-by-Step Example
### 1. Define Your Component Catalog
`lib/catalog.ts`:
```typescript
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react";
import { z } from "zod";
export const catalog = defineCatalog(schema, {
components: {
RecipeHeader: {
props: z.object({
title: z.string(),
chef: z.string(),
prepTime: z.string(),
}),
description: "Header with recipe info",
},
IngredientList: {
props: z.object({
title: z.string(),
ingredients: z.array(
z.object({
name: z.string(),
quantity: z.string(),
})
),
}),
description: "List of ingredients",
},
// ... more components
},
actions: {},
});
```
**This is your guardrail**: AI can only use these components.
### 2. Map Components to React
`lib/registry.tsx`:
```typescript
import { defineRegistry } from "@json-render/react";
import { catalog } from "./catalog";
export const { registry } = defineRegistry(catalog, {
components: {
RecipeHeader: ({ props }) => (
{props.title}
👨🍳 Chef: {props.chef}
⏱️ Prep: {props.prepTime}
),
IngredientList: ({ props }) => (
{props.title}
{props.ingredients.map((ing, i) => (
-
{ing.quantity} {ing.name}
))}
),
// ... more implementations
},
});
```
### 3. Create a JSON Spec
`lib/recipes.ts`:
```typescript
const recipe = {
root: "root", // Start rendering from this element
elements: {
root: {
type: "RecipeCard", // Component from catalog
props: {
title: "Crêpes Suzette",
description: "Classic French dessert"
},
children: ["header", "ingredients"] // Refs to other elements
},
header: {
type: "RecipeHeader",
props: {
title: "Crêpes Suzette",
chef: "Auguste Escoffier",
prepTime: "45 minutes"
}
},
ingredients: {
type: "IngredientList",
props: {
title: "Ingredients",
ingredients: [
{ quantity: "200g", name: "Flour" },
{ quantity: "4", name: "Eggs" },
{ quantity: "500ml", name: "Milk" }
]
}
}
}
};
```
**This is what AI generates** (but here we've pre-written it for the demo).
### 4. Render with json-render
`app/page.tsx`:
```typescript
import { Renderer } from "@json-render/react";
import { registry, Provider } from "@/lib/registry";
import { recipes } from "@/lib/recipes";
export default function Home() {
return (
{recipes.map((recipe, index) => (
))}
);
}
```
**Magic happens here**: The `Renderer` takes your spec + registry and outputs fully-styled React components!
## What Gets Rendered
The spec above becomes:
```jsx
Crêpes Suzette
Classic French dessert
Crêpes Suzette
👨🍳 Chef: Auguste Escoffier
⏱️ Prep: 45 minutes
Ingredients
- 200g Flour
- 4 Eggs
- 500ml Milk
```
## Why This Matters
### Without json-render:
- AI generates raw HTML/JSX → **Security risk** (XSS, code injection)
- No type safety → **Runtime errors**
- Unpredictable output → **Broken UIs**
### With json-render:
- ✅ AI can only use predefined components (guardrailed)
- ✅ Zod schemas enforce type safety (predictable)
- ✅ Your React components control the rendering (safe)
- ✅ Stream rendering as AI generates (fast)
## In Production with AI
```typescript
// User types prompt
const userPrompt = "Show me a recipe for chocolate chip cookies";
// AI generates spec (using your catalog as context)
const aiGeneratedSpec = await ai.generate({
prompt: userPrompt,
catalog: catalog.prompt(), // Gives AI the component vocabulary
});
// Render safely
```
**Result**: AI-generated UIs that are:
1. **Safe** - Can't inject malicious code
2. **Type-safe** - Matches your schemas
3. **Beautiful** - Uses your styled components
4. **Fast** - Streams as AI generates
## The Power
You define the components once. Then:
- AI can generate infinite variations
- Users can describe UIs in natural language
- Your app stays safe and consistent
- No manual UI coding needed
**That's json-render.**
---
Check the full code in `lib/` to see it in action! 🚀