json-render (vercel-labs fork) + real Image src, Pressable, self-contained Lightbox & Modal
|
|
5 сар өмнө | |
|---|---|---|
| .changeset | 5 сар өмнө | |
| .github | 5 сар өмнө | |
| .husky | 5 сар өмнө | |
| apps | 5 сар өмнө | |
| examples | 5 сар өмнө | |
| packages | 5 сар өмнө | |
| skills | 5 сар өмнө | |
| .gitignore | 5 сар өмнө | |
| .npmrc | 5 сар өмнө | |
| AGENTS.md | 5 сар өмнө | |
| LICENSE | 5 сар өмнө | |
| README.md | 5 сар өмнө | |
| package.json | 5 сар өмнө | |
| pnpm-lock.yaml | 5 сар өмнө | |
| pnpm-workspace.yaml | 5 сар өмнө | |
| turbo.json | 5 сар өмнө | |
| vitest.config.ts | 5 сар өмнө |
Predictable. Guardrailed. Fast.
Let end users generate dashboards, widgets, apps, and videos from prompts — safely constrained to components you define.
npm install @json-render/core @json-render/react
# or for video
npm install @json-render/core @json-render/remotion
When users prompt for UI, you need guarantees. json-render gives AI a constrained vocabulary so output is always predictable:
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react";
import { z } from "zod";
const catalog = defineCatalog(schema, {
components: {
Card: {
props: z.object({ title: z.string() }),
description: "A card container",
},
Metric: {
props: z.object({
label: z.string(),
value: z.string(),
format: z.enum(["currency", "percent", "number"]).nullable(),
}),
description: "Display a metric value",
},
Button: {
props: z.object({
label: z.string(),
action: z.string(),
}),
description: "Clickable button",
},
},
actions: {
export_report: { description: "Export dashboard to PDF" },
refresh_data: { description: "Refresh all metrics" },
},
});
import { defineRegistry, Renderer } from "@json-render/react";
const { registry } = defineRegistry(catalog, {
components: {
Card: ({ props, children }) => (
<div className="card">
<h3>{props.title}</h3>
{children}
</div>
),
Metric: ({ props }) => (
<div className="metric">
<span>{props.label}</span>
<span>{format(props.value, props.format)}</span>
</div>
),
Button: ({ props, onAction }) => (
<button onClick={() => onAction?.({ name: props.action })}>
{props.label}
</button>
),
},
});
function Dashboard({ spec }) {
return <Renderer spec={spec} registry={registry} />;
}
That's it. AI generates JSON, you render it safely.
| Package | Description |
|---|---|
@json-render/core |
Schemas, catalogs, AI prompts, SpecStream utilities |
@json-render/react |
React renderer, contexts, hooks |
@json-render/remotion |
Remotion video renderer, timeline schema |
import { defineRegistry, Renderer } from "@json-render/react";
import { schema } from "@json-render/react";
// Element tree spec format
const spec = {
root: {
type: "Card",
props: { title: "Hello" },
children: [
{ type: "Button", props: { label: "Click me" } }
]
}
};
// defineRegistry creates a type-safe component registry
const { registry } = defineRegistry(catalog, { components });
<Renderer spec={spec} registry={registry} />
import { Player } from "@remotion/player";
import { Renderer, schema, standardComponentDefinitions } from "@json-render/remotion";
// Timeline spec format
const spec = {
composition: { id: "video", fps: 30, width: 1920, height: 1080, durationInFrames: 300 },
tracks: [{ id: "main", name: "Main", type: "video", enabled: true }],
clips: [
{ id: "clip-1", trackId: "main", component: "TitleCard", props: { title: "Hello" }, from: 0, durationInFrames: 90 }
],
audio: { tracks: [] }
};
<Player
component={Renderer}
inputProps={{ spec }}
durationInFrames={spec.composition.durationInFrames}
fps={spec.composition.fps}
compositionWidth={spec.composition.width}
compositionHeight={spec.composition.height}
/>
Stream AI responses progressively:
import { createSpecStreamCompiler } from "@json-render/core";
const compiler = createSpecStreamCompiler<MySpec>();
// Process chunks as they arrive
const { result, newPatches } = compiler.push(chunk);
setSpec(result); // Update UI with partial result
// Get final result
const finalSpec = compiler.getResult();
Generate system prompts from your catalog:
const systemPrompt = catalog.prompt();
// Includes component descriptions, props schemas, available actions
{
"type": "Alert",
"props": { "message": "Error occurred" },
"visible": {
"and": [
{ "path": "/form/hasError" },
{ "not": { "path": "/form/errorDismissed" } }
]
}
}
{
"type": "Metric",
"props": {
"label": "Revenue",
"value": "{{data.revenue}}"
}
}
git clone https://github.com/vercel-labs/json-render
cd json-render
pnpm install
pnpm dev
flowchart LR
A[User Prompt] --> B[AI + Catalog]
B --> C[JSON Spec]
C --> D[Renderer]
B -.- E([guardrailed])
C -.- F([predictable])
D -.- G([streamed])
Apache-2.0