JSON-Render: Biblioteca de UI controlada por prompts de IA para React
JSON‑Render: Biblioteca de UI controlada por prompts de IA para React
En la era de los modelos de lenguaje extensos, los desarrolladores están constantemente buscando formas de convertir indicaciones de texto puro en interfaces de usuario accionables. JSON‑Render llena ese nicho al ofrecer a la IA un vocabulario predecible y seguro, de modo que la salida sea siempre un árbol JSON que puedes renderizar con React — sin sorpresas, sin agujeros de seguridad.
¿Qué es JSON‑Render?
JSON‑Render es una herramienta ligera orientada a TypeScript que consta de dos paquetes NPM:
- @json-render/core – definiciones de esquema, guardrails, lógica de visibilidad y manejadores de acciones.
- @json-render/react – componentes de React, hooks y renderizadores que convierten el JSON en una UI en vivo.
Beneficios clave:
| Característica | Razón para importarlo |
|---|---|
| Controlado | A la IA se le restringe un catálogo de tipos de componentes permitidos, evitando la inyección de código malicioso. |
| Predecible | El JSON sigue un esquema Zod. Cada propiedad puede ser verificada en tiempo de ejecución. |
| Rápido | El flujo puede renderizarse a medida que el modelo envía datos, lo que permite a los usuarios ver actualizaciones en tiempo real. |
| Componible | Combina tus propios componentes de React con guardrails; la biblioteca es independiente del estilo. |
Guía de Inicio Rápido
A continuación se muestra una guía paso a paso de un ejemplo mínimo. Supone un proyecto Node nuevo con pnpm.
# Clonar y arrancar
git clone https://github.com/vercel-labs/json-render
cd json-render
pnpm install
pnpm dev
El comando dev inicia cuatro servicios: *
localhost:3000– Docs y Playground *localhost:3001– Aplicación de tablero de ejemplo * Endpoints de WebSocket para la API * Un backend compatible con ChatGPT local (ver el repositorio para integración LLM personalizada)
1. Define el Catálogo
En packages/core/src/catalog.ts, declaras cada componente que la IA puede usar. Aquí tienes un ejemplo compacto:
import { createCatalog } from '@json-render/core'
import { z } from 'zod'
const catalog = createCatalog({
components: {
Card: {
props: z.object({ title: z.string() }),
hasChildren: true,
},
Metric: {
props: z.object({
label: z.string(),
valuePath: z.string(),
format: z.enum(['currency', 'percent', 'number']),
}),
},
Button: {
props: z.object({ label: z.string(), action: ActionSchema }),
},
},
actions: {
export_report: { description: 'Export dashboard to PDF' },
refresh_data: { description: 'Refresh all metrics' },
},
})
export default catalog
ActionSchemaes un esquema Zod que importas de @json-render/core y que valida la forma de una carga útil de acción.
2. Registrar Renderizadores de React
Crea un pequeño registro que mapee nombres de componentes a elementos React reales.
const registry = {
Card: ({ element, children }) => (
<div className="card">
<h3>{element.props.title}</h3>
{children}
</div>
),
Metric: ({ element }) => {
const value = useDataValue(element.props.valuePath)
return <div className="metric">{format(value)}</div>
},
Button: ({ element, onAction }) => (
<button onClick={() => onAction(element.props.action)}>
{element.props.label}
</button>
),
}
3. Conectar Todo
import { useUIStream, DataProvider, ActionProvider, Renderer } from '@json-render/react'
function Dashboard() {
const { tree, send } = useUIStream({ api: '/api/generate' })
return (
<DataProvider initialData={{ revenue: 125000, growth: 0.15 }}>
<ActionProvider actions={{
export_report: () => downloadPDF(),
refresh_data: () => refetch(),
}}>
<input
placeholder="Crea un tablero de ingresos…"
onKeyDown={(e) => e.key === 'Enter' && send(e.target.value)}
/>
<Renderer tree={tree} components={registry} />
</ActionProvider>
</DataProvider>
)
}
Cuando un usuario escribe una indicación de lenguaje natural y pulsa Enter, la biblioteca transmite la respuesta JSON de la IA, el registro lo renderiza y cualquier acción definida activa funciones de callback.
Funciones Avanzadas
Visibilidad Condicional
Muestra u oculta elementos según datos, autenticación o lógica personalizada:
{
"type": "Alert",
"props": { "message": "Error occurred" },
"visible": { "and": [ { "path": "/form/hasError" }, { "not": { "path": "/form/errorDismissed" } } ] }
}
Acciones Ricas con Confirmación
{
"type": "Button",
"props": {
"label": "Refund Payment",
"action": {
"name": "refund",
"params": { "paymentId": { "path": "/selected/id" } },
"confirm": { "title": "Confirm Refund", "variant": "danger" }
}
}
}
Validación Incorporada
{
"type": "TextField",
"props": {
"label": "Email",
"valuePath": "/form/email",
"checks": [
{ "fn": "required", "message": "Email is required" },
{ "fn": "email", "message": "Invalid email" }
],
"validateOn": "blur"
}
}
Cuándo Usar JSON‑Render
- Prototipado rápido – Convierte indicaciones en dashboards funcionales en minutos.
- Generación de UI desacoplada – Separa tu sistema de diseño del LLM.
- Renderizado UI seguro – Los guardrails evitan la inyección de componentes arbitrarios.
- Multiplataforma – El core se puede usar en React, React‑Native o cualquier framework UI que consuma JSON.
Cómo Empezar
Clona el repositorio, añade tu propio backend LLM o usa el adaptador OpenAI proporcionado, y ejecuta pnpm dev. Tu nuevo proyecto React importará automáticamente la lógica de renderizado. Siéntete libre de ampliar el catálogo o reemplazar el registry con componentes estilizados de tu sistema de diseño.
Tip – Utiliza la función integrada de docs y playground en
localhost:3000para experimentar con prompts, cambios en el catálogo y vista previa en vivo sin tocar el código.
Conclusión
JSON‑Render brinda a los desarrolladores una forma limpia y con tipado seguro de permitir que las LLM generen componentes UI. Al mantener la salida en un formato JSON predecible y protegido, conservas el control sobre la seguridad, el rendimiento y la experiencia del usuario, todo mientras ofreces la potente comodidad del diseño UI mediante lenguaje natural. ¿Listo para incorporar dashboards generados por IA en tu producto? Obtén el paquete en NPM y comienza a experimentar hoy mismo.