Comprehensive examples demonstrating all features of vercel-labs/json-render
json-render is a Generative UI framework by Vercel Labs that enables AI to generate dynamic, personalized UIs from natural language prompts while maintaining predictability and safety.
| Feature | Description |
|---|---|
| 🛡️ Guardrailed | AI can only use components defined in Catalog |
| 📊 Predictable | JSON output always matches predefined Schema |
| ⚡ Streaming | Progressive UI updates as model responds |
| 🌐 Cross-Platform | React, Vue, React Native, Remotion, PDF, Email, Image |
| 📦 Built-in Components | 36 pre-built shadcn/ui components |
# Clone the repository
git clone https://github.com/wangjs-jacky/json-render-examples.git
# Navigate to project
cd json-render-examples
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Open browser
open http://localhost:3000| # | Example | Description |
|---|---|---|
| 01 | Basic Rendering | Catalog, Registry, Renderer fundamentals |
| 02 | State Management | StateStore, $state, $bindState |
| 03 | Visibility Conditions | visible, $cond, AND/OR logic |
| 04 | Dynamic Props | $computed, $template, $cond |
| 05 | Actions System | actions, setState, handlers |
| 06 | Repeat Scope | repeat, $item, $index |
| 07 | Streaming Render | SpecStream, JSON Patch |
| 08 | Form Validation | checks, validateOn |
| 09 | shadcn Components | 36 pre-built components |
| 10 | AI Integration | AI SDK, prompt generation |
| 11 | Nested Format | nestedToFlat conversion |
| 12 | Spec Validation | validateSpec, autoFixSpec |
| 13 | State Watchers | watch, cascading selects |
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Catalog │────▶│ Registry │────▶│ Renderer │
│ (Vocabulary)│ │(Implementation)│ │ (Renderer) │
└─────────────┘ └─────────────┘ └─────────────┘
const catalog = defineCatalog(schema, {
components: {
Card: {
props: z.object({ title: z.string() }),
description: "Card container",
},
},
actions: {
submit: { description: "Submit form" },
},
});const { registry } = defineRegistry(catalog, {
components: {
Card: ({ props, children }) => (
<div className="card">
<h3>{props.title}</h3>
{children}
</div>
),
},
});const spec = {
root: "card-1",
elements: {
"card-1": {
type: "Card",
props: { title: "Hello" },
children: [],
},
},
};| Expression | Description |
|---|---|
{ $state: "/path" } |
Read value from state model |
{ $bindState: "/path" } |
Two-way binding to state |
{ $item: "field" } |
Read field from repeat item |
{ $index: true } |
Get repeat index |
{ $cond, $then, $else } |
Conditional expression |
{ $computed: "fn" } |
Call computed function |
{ $template: "text ${/path}" } |
Template string interpolation |
// Simple condition
visible: { $state: "/isLoggedIn" }
// Negation
visible: { $state: "/isAdmin", not: true }
// Comparison
visible: { $state: "/count", gt: 5 }
// AND conditions
visible: [{ $state: "/a" }, { $state: "/b" }]
// OR conditions
visible: { $or: [{ $state: "/a" }, { $state: "/b" }] }// Built-in setState action
on: {
press: {
action: "setState",
actionParams: { statePath: "/count", value: 0 },
confirm: { title: "Confirm reset?" },
onSuccess: { action: "notify", actionParams: { message: "Success" } },
},
}{
type: "TodoItem",
repeat: { statePath: "/todos", key: "id" },
props: {
title: { $item: "title" },
index: { $index: true },
},
}json-render-examples/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── page.tsx # Home page
│ │ ├── layout.tsx # Layout
│ │ ├── examples/ # Example page routes
│ │ └── examples.ts # Example config
│ ├── examples/ # Example implementations
│ │ ├── 01-basic-rendering.tsx
│ │ ├── 02-state-management.tsx
│ │ └── ...
│ └── lib/ # Utilities
│ ├── catalog.ts
│ └── registry.tsx
├── docs/
│ └── FEATURES.md # Detailed feature docs
├── README.md # English (this file)
├── README_CN.md # Chinese
└── package.json
Apache-2.0