📌 项目地址:vercel-labs/json-render | ⭐ 14,913 颗星 | 🔧 TypeScript | 📜 Apache-2.0
这个项目解决一个具体问题
让AI根据文字描述生成用户界面,听起来很美。但直接让大模型输出HTML或JSX,结果可能包含你没预料到的元素或行为,这很危险。vercel-labs/json-render 的思路是:你先给AI一个“组件工具箱”和一份严格的“设计规范”,AI只能在这个范围内拼装界面。
它本质上是一个中间层。你的应用定义好可用的组件(比如按钮、卡片、图表)和它们的属性规则(比如按钮必须有label和action属性),这些定义构成一个catalog。AI的任务就是根据用户的提示,输出一份符合这个catalog规则的JSON结构。最后,Renderer组件把这份JSON渲染成真正的UI。整个过程,AI的创造力被限制在你划定的安全区内。
核心:用代码定义可用的“积木”
README里的“Quick Start”部分直接展示了工作流。第一步就是用defineCatalog定义你的组件目录和动作。
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react/schema";
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" },
},
});
这里用Zod定义每个组件的属性Schema。AI生成的JSON里,一个Button组件就必须包含label和action两个字段,且类型要匹配。这个目录就是AI的“能力边界”。
为“积木”注入生命:跨平台渲染
定义了目录,还需要告诉程序每个组件长什么样、怎么工作。这通过defineRegistry完成。README的示例是针对React的:
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">
<label>{props.label}</label>
<span>{props.value}</span>
</div>
),
Button: ({ props }) => (
<button onClick={() => console.log(props.action)}>
{props.label}
</button>
),
},
});
最关键的是,这套catalog定义是平台无关的。同一个目录,可以配套不同的渲染包,从而输出到不同平台。README列出了完整的安装命令,覆盖了主流场景:
# React
npm install @json-render/core @json-render/react
# 带预置shadcn/ui组件
npm install @json-render/shadcn
# React Native
npm install @json-render/core @json-render/react-native
# Vue
npm install @json-render/core @json-render/vue
# Svelte
npm install @json-render/core @json-render/svelte
# SolidJS
npm install @json-render/core @json-render/solid
# 终端UI
npm install @json-render/core @json-render/ink ink react
# Next.js全栈应用
npm install @json-render/core @json-render/react @json-render/next
# 3D场景
npm install @json-render/core @json-render/react-three-fiber @react-three/fiber @react-three/drei three
这意味着,你可以设计一个“仪表盘”目录,它既能在网页上渲染成React组件,也能在命令行里用Ink显示,甚至生成为PDF或视频帧。设计规范统一,输出渠道多样。
我的看法
json-render提供了一种可行的路径,将大语言模型的生成能力与工程应用的可靠性要求结合起来。它没有试图让AI“自由发挥”,而是通过预设的Schema和组件目录,将AI的输出引导到可控的、结构化的数据格式上,再由确定的渲染层转化为实际UI。这解决的是生成式UI从“好玩”到“能用”之间的信任和安全问题。
根据README,项目自带36个预构建的shadcn/ui组件,对于使用React技术栈的项目来说,开箱体验会更顺畅。对于其他平台,则需要自己实现组件注册。