From ork
Defines Zod-typed component catalogs for json-render to constrain AI-generated UIs, includes 29 shadcn components, YAML mode for token efficiency. Use for React/Vue/Svelte/React Native genui projects.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ork:json-render-catalogThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
json-render (Vercel Labs, 12.9K stars, Apache-2.0) is a framework for AI-safe generative UI. AI generates flat-tree JSON (or YAML) specs constrained to a developer-defined catalog — the catalog is the contract between your design system and AI output. If a component or prop is not in the catalog, AI cannot generate it.
json-render (Vercel Labs, 12.9K stars, Apache-2.0) is a framework for AI-safe generative UI. AI generates flat-tree JSON (or YAML) specs constrained to a developer-defined catalog — the catalog is the contract between your design system and AI output. If a component or prop is not in the catalog, AI cannot generate it.
| Category | Rules | Impact | When to Use |
|---|---|---|---|
| Catalog Definition | 1 | HIGH | Defining component catalogs with Zod |
| Prop Constraints | 1 | HIGH | Constraining AI-generated props for safety |
| shadcn Catalog | 1 | MEDIUM | Using pre-built shadcn components |
| Token Optimization | 1 | MEDIUM | Reducing token usage with YAML mode |
| Actions & State | 1 | MEDIUM | Adding interactivity to specs |
Total: 5 rules across 5 categories
<Render> component validates and renders each elementThe catalog is the safety boundary. AI can only reference types that exist in the catalog, and props are validated against Zod schemas at runtime. This prevents hallucinated components and invalid props from reaching the UI.
import { defineCatalog } from '@json-render/core'
import { z } from 'zod'
export const catalog = defineCatalog({
Card: {
props: z.object({
title: z.string(),
description: z.string().optional(),
}),
children: true,
},
Button: {
props: z.object({
label: z.string(),
variant: z.enum(['default', 'destructive', 'outline', 'ghost']),
}),
children: false,
},
StatGrid: {
props: z.object({
items: z.array(z.object({
label: z.string(),
value: z.string(),
trend: z.enum(['up', 'down', 'flat']).optional(),
})).max(20),
}),
children: false,
},
})
import type { CatalogComponents } from '@json-render/react'
import type { catalog } from './catalog'
export const components: CatalogComponents<typeof catalog> = {
Card: ({ title, description, children }) => (
<div className="rounded-lg border p-4">
<h3 className="font-semibold">{title}</h3>
{description && <p className="text-muted-foreground">{description}</p>}
{children}
</div>
),
Button: ({ label, variant }) => (
<button className={cn('btn', `btn-${variant}`)}>{label}</button>
),
StatGrid: ({ items }) => (
<div className="grid grid-cols-3 gap-4">
{items.map((item) => (
<div key={item.label}>
<span>{item.label}</span>
<strong>{item.value}</strong>
</div>
))}
</div>
),
}
import { Render } from '@json-render/react'
import { catalog } from './catalog'
import { components } from './components'
function App({ spec }: { spec: JsonRenderSpec }) {
return <Render catalog={catalog} components={components} spec={spec} />
}
The JSON spec is a flat tree — no nesting, just IDs and references. Load references/spec-format.md for full documentation.
{
"root": "card-1",
"elements": {
"card-1": {
"type": "Card",
"props": { "title": "Dashboard" },
"children": ["chart-1", "btn-1"]
},
"btn-1": {
"type": "Button",
"props": { "label": "View Details", "variant": "default" }
}
}
}
{
"root": "card-1",
"elements": {
"card-1": {
"type": "Card",
"props": { "title": "Dashboard" },
"children": ["chart-1", "btn-1"],
"on": { "press": { "action": "setState", "path": "/view", "value": "detail" } },
"watch": { "/data": { "action": "load_data", "url": "/api/stats" } }
}
},
"state": { "/activeTab": "overview" }
}
Load rules/action-state.md for event handlers, watch bindings, and state adapter patterns.
For one-shot (non-streaming) generation, YAML specs use ~30% fewer tokens than JSON:
root: card-1
elements:
card-1:
type: Card
props:
title: Dashboard
children: [chart-1, btn-1]
btn-1:
type: Button
props:
label: View Details
variant: default
Use JSON for streaming (JSON Patch RFC 6902 over JSONL requires JSON). Use YAML for one-shot generation where token cost matters. Load rules/token-optimization.md for selection criteria.
json-render supports progressive rendering during streaming. As the AI generates spec elements, they render immediately — the user sees the UI building in real-time. This uses JSON Patch (RFC 6902) operations streamed over JSONL:
{"op":"add","path":"/elements/card-1","value":{"type":"Card","props":{"title":"Dashboard"},"children":[]}}
{"op":"add","path":"/elements/btn-1","value":{"type":"Button","props":{"label":"Save","variant":"default"}}}
{"op":"add","path":"/elements/card-1/children/-","value":"btn-1"}
Elements render as soon as their props are complete — no waiting for the full spec.
The @json-render/shadcn package provides a production-ready catalog of 29 components with Zod schemas already defined. Load rules/shadcn-catalog.md for the full component list and when to extend vs use as-is.
import { shadcnCatalog, shadcnComponents } from '@json-render/shadcn'
import { mergeCatalogs } from '@json-render/core'
// Use as-is
<Render catalog={shadcnCatalog} components={shadcnComponents} spec={spec} />
// Or merge with custom components
const catalog = mergeCatalogs(shadcnCatalog, customCatalog)
23 packages covering web, mobile, 3D, codegen, and state management. Load references/package-ecosystem.md for the full list organized by category.
Use json-render when:
Do NOT use json-render when:
If you have existing custom generative UI (hand-rolled JSON-to-component mapping), load references/migration-from-genui.md for a step-by-step migration guide.
How to define catalogs with defineCatalog() and Zod schemas.
| Rule | File | Key Pattern |
|---|---|---|
| Catalog Definition | rules/catalog-definition.md | defineCatalog with Zod schemas, children types |
Constraining props to prevent AI hallucination.
| Rule | File | Key Pattern |
|---|---|---|
| Prop Constraints | rules/prop-constraints.md | z.enum, z.string().max(), z.array().max() |
Using the 29 pre-built shadcn components.
| Rule | File | Key Pattern |
|---|---|---|
| shadcn Catalog | rules/shadcn-catalog.md | @json-render/shadcn components and extension |
Choosing JSON vs YAML for token efficiency.
| Rule | File | Key Pattern |
|---|---|---|
| Token Optimization | rules/token-optimization.md | YAML for one-shot, JSON for streaming |
Adding interactivity with events, watchers, and state.
| Rule | File | Key Pattern |
|---|---|---|
| Action & State | rules/action-state.md | on events, watch reactivity, state adapters |
| Decision | Recommendation |
|---|---|
| Custom vs shadcn catalog | Start with shadcn, extend with custom types for domain-specific components |
| JSON vs YAML spec format | YAML for one-shot (30% fewer tokens), JSON for streaming |
| Zod constraint strictness | Tighter is better — use z.enum over z.string, z.array().max() over unbounded |
| State management adapter | Match your app's existing state library (Zustand, Redux, Jotai, XState) |
z.any() or z.unknown() in catalog props — defeats the purpose of catalog constraints, AI can generate anythingmergeCatalogs() when combining shadcn + custom — manual merging loses type safety.max() on arrays — AI can generate unbounded lists that break layoutsork:ai-ui-generation — AI-assisted UI generation patterns for v0, Bolt, Cursorork:ui-components — shadcn/ui component patterns and CVA variantsork:component-search — Finding and evaluating React/Vue componentsork:design-to-code — Converting designs to production codenpx claudepluginhub yonatangross/orchestkit --plugin orkProvides patterns for AI-assisted UI generation with json-render, v0, Bolt, Cursor: prompt engineering, review checklists, design token injection, refactoring for design systems, CI quality gates. For generating, reviewing, integrating AI UI components.
Generates structured JSON UI specs from a catalog of components, selectable renderers (React, shadcn, RN, etc.), and integrates with gem skills for visual assets. Supports MCP Apps delivery in chat interfaces.
Generative UI implementation patterns for AI SDK RSC including server-side streaming components, dynamic UI generation, and client-server coordination. Use when implementing generative UI, building AI SDK RSC, creating streaming components, or when user mentions generative UI, React Server Components, dynamic UI, AI-generated interfaces, or server-side streaming.