- Replace .eslintrc.cjs with eslint.config.mjs (ESLint 9 flat config)
using direct eslint-plugin-solid + @typescript-eslint/parser approach
- Add @typescript-eslint/parser to root devDependencies
- Add main/module/types top-level fields to packages/core/package.json
- Add resolve.conditions to packages/core/vite.config.ts
- Create packages/core/tsconfig.test.json for test type-checking
- Remove empty paths:{} from packages/core/tsconfig.json
11 KiB
The Generative UI Framework
AI → json-render → UI
Generate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.
Create a contact form with name, email, and message
Create a login form with email and passwordBuild a feedback form with rating stars
jsonnestedstreamcatalog
{"op":"add","path":"/root","value":"card"}
{"op":"add","path":"/elements/name","value":{"type":"Input","props":{"label":"Name","name":"name","statePath":"/form/name","checks":[{"type":"required","message":"Name is required"}]}}}
{"op":"add","path":"/elements/email","value":{"type":"Input","props":{"label":"Email","name":"email","type":"email","statePath":"/form/email","checks":[{"type":"required","message":"Email is required"},{"type":"email","message":"Please enter a valid email"}]}}}
{
"root": "card",
"state": {
"form": {
"name": "",
"email": "",
"message": ""
}
},
"elements": {
"card": {
"type": "Card",
"props": {
"title": "Contact Us",
"maxWidth": "md"
},
"children": [\
"name",\
"email"\
]
},
"name": {
"type": "Input",
"props": {
"label": "Name",
"name": "name",
"statePath": "/form/name",
"checks": [\
{\
"type": "required",\
"message": "Name is required"\
}\
]
}
},
"email": {
"type": "Input",
"props": {
"label": "Email",
"name": "email",
"type": "email",
"statePath": "/form/email",
"checks": [\
{\
"type": "required",\
"message": "Email is required"\
},\
{\
"type": "email",\
"message": "Please enter a valid email"\
}\
]
}
}
}
}
{
"state": {
"form": {
"name": "",
"email": "",
"message": ""
}
},
"elements": {
"type": "Card",
"props": {
"title": "Contact Us",
"maxWidth": "md"
},
"children": [\
{\
"type": "Input",\
"props": {\
"label": "Name",\
"name": "name",\
"statePath": "/form/name",\
"checks": [\
{\
"type": "required",\
"message": "Name is required"\
}\
]\
}\
},\
{\
"type": "Input",\
"props": {\
"label": "Email",\
"name": "email",\
"type": "email",\
"statePath": "/form/email",\
"checks": [\
{\
"type": "required",\
"message": "Email is required"\
},\
{\
"type": "email",\
"message": "Please enter a valid email"\
}\
]\
}\
}\
]
}
}
components (39)actions (6)
Accordion
Collapsible sections. Items as [{title, content}]. Type 'single' (default) or 'multiple'.
items: arraytype: enum?
Alert
Alert banner
title: stringmessage: string?type: enum?
Avatar
User avatar with fallback initials
src: string?name: stringsize: enum?
Badge
Status badge
text: stringvariant: enum?
BarGraph
Vertical bar chart
title: string?data: array
Button
Clickable button. Bind on.press for handler.
label: stringvariant: enum?disabled: boolean?
on.press
ButtonGroup
Segmented button group. Use { $bindState } on selected for selected value.
buttons: arrayselected: string?
on.change
Cardslots: default
Container card for content sections. Use for forms/content boxes, NOT for page headers.
title: string?description: string?maxWidth: enum?centered: boolean?
Carousel
Horizontally scrollable carousel of cards.
items: array
Checkbox
Checkbox input. Use { $bindState } on checked for binding.
label: stringname: stringchecked: boolean?
on.change
Collapsibleslots: default
Collapsible section with trigger. Children render inside.
title: stringdefaultOpen: boolean?
Dialogslots: default
Modal dialog. Set openPath to a boolean state path. Use setState to toggle.
title: stringdescription: string?openPath: string
Drawerslots: default
Bottom sheet drawer. Set openPath to a boolean state path. Use setState to toggle.
title: stringdescription: string?openPath: string
DropdownMenu
Dropdown menu with trigger button and selectable items.
label: stringitems: array
on.select
Gridslots: default
Grid layout (1-6 columns)
columns: number?gap: enum?
Heading
Heading text (h1-h4)
text: stringlevel: enum?
Image
Placeholder image (displays alt text in a styled box)
alt: stringwidth: number?height: number?
Input
Text input field. Use { $bindState } on value for two-way binding. Use checks for validation (e.g. required, email, minLength).
label: stringname: stringtype: enum?placeholder: string?value: string?checks: array?
on.submiton.focuson.blur
LineGraph
Line chart with points
title: string?data: array
Link
Anchor link. Bind on.press for click handler.
label: stringhref: string
on.press
Pagination
Page navigation. Use { $bindState } on page for current page number.
totalPages: numberpage: number?
on.change
Popover
Popover that appears on click of trigger.
trigger: stringcontent: string
Progress
Progress bar (value 0-100)
value: numbermax: number?label: string?
Radio
Radio button group. Use { $bindState } on value for binding.
label: stringname: stringoptions: arrayvalue: string?
on.change
Rating
Star rating display
value: numbermax: number?label: string?
Select
Dropdown select input. Use { $bindState } on value for binding. Use checks for validation.
label: stringname: stringoptions: arrayplaceholder: string?value: string?checks: array?
on.change
Separator
Visual separator line
orientation: enum?
Skeleton
Loading placeholder skeleton
width: string?height: string?rounded: boolean?
Slider
Range slider input. Use { $bindState } on value for binding.
label: string?min: number?max: number?step: number?value: number?
on.change
Spinner
Loading spinner indicator
size: enum?label: string?
Stackslots: default
Flex container for layouts
direction: enum?gap: enum?align: enum?justify: enum?
Switch
Toggle switch. Use { $bindState } on checked for binding.
label: stringname: stringchecked: boolean?
on.change
Table
Data table. columns: header labels. rows: 2D array of cell strings, e.g. "Alice","admin"],["Bob","user".
columns: arrayrows: arraycaption: string?
Tabs
Tab navigation. Use { $bindState } on value for active tab binding.
tabs: arraydefaultValue: string?value: string?
on.change
Text
Paragraph text
text: stringvariant: enum?
Textarea
Multi-line text input. Use { $bindState } on value for binding. Use checks for validation.
label: stringname: stringplaceholder: string?rows: number?value: string?checks: array?
Toggle
Toggle button. Use { $bindState } on pressed for state binding.
label: stringpressed: boolean?variant: enum?
on.change
ToggleGroup
Group of toggle buttons. Type 'single' (default) or 'multiple'. Use { $bindState } on value.
items: arraytype: enum?value: string?
on.change
Tooltip
Hover tooltip. Shows content on hover over text.
content: stringtext: string
live renderstatic code
export
Contact Us
Name
npm install @json-render/core @json-render/react
01
Define Your Catalog
Set the guardrails. Define which components, actions, and data bindings AI can use.
02
AI Generates
Describe what you want. AI generates JSON constrained to your catalog. Every interface is unique.
03
Render Instantly
Stream the response. Your components render progressively as JSON arrives.
Define your catalog
Components, actions, and validation functions.
import { defineSchema, defineCatalog } from '@json-render/core';
import { z } from 'zod';
const schema = defineSchema({ /* ... */ });
export const catalog = defineCatalog(schema, {
components: {
Card: {
props: z.object({
title: z.string(),
description: z.string().nullable(),
}),
hasChildren: true,
},
Metric: {
props: z.object({
label: z.string(),
statePath: z.string(),
format: z.enum(['currency', 'percent']),
}),
},
},
actions: {
export: { params: z.object({ format: z.string() }) },
},
});
Show all
AI generates JSON
Constrained output that your components render natively.
{
"root": "dashboard",
"elements": {
"dashboard": {
"type": "Card",
"props": {
"title": "Revenue Dashboard"
},
"children": ["revenue"]
},
"revenue": {
"type": "Metric",
"props": {
"label": "Total Revenue",
"statePath": "/metrics/revenue",
"format": "currency"
}
}
}
}
Export as Code
Export generated UI as standalone React components. No runtime dependencies required.
Generated UI Tree
AI generates a JSON structure from the user's prompt.
{
"root": "card",
"elements": {
"card": {
"type": "Card",
"props": { "title": "Revenue" },
"children": ["metric", "chart"]
},
"metric": {
"type": "Metric",
"props": {
"label": "Total Revenue",
"statePath": "analytics/revenue",
"format": "currency"
}
},
"chart": {
"type": "Chart",
"props": {
"statePath": "analytics/salesByRegion"
}
}
}
}
Show all
Exported React Code
Export as a standalone Next.js project with all components.
"use client";
import { Card, Metric, Chart } from "@/components/ui";
const data = {
analytics: {
revenue: 125000,
salesByRegion: [\
{ label: "US", value: 45000 },\
{ label: "EU", value: 35000 },\
],
},
};
export default function Page() {
return (
<Card data={data} title="Revenue">
<Metric
data={data}
label="Total Revenue"
statePath="analytics/revenue"
format="currency"
/>
<Chart data={data} statePath="analytics/salesByRegion" />
</Card>
);
}
Show all
The export includespackage.json, component files, styles, and everything needed to run independently.
Features
Generative UI
Generate dynamic, personalized interfaces from prompts with AI
Guardrails
AI can only use components you define in the catalog
Streaming
Progressive rendering as JSON streams from the model
React & React Native
Render on web and mobile from the same catalog and spec format
Data Binding
Connect props to state with $state, $item, $index, and two-way binding
Code Export
Export as standalone React code with no runtime dependencies
Get started
npm install @json-render/core @json-render/react
Ask AI ⌘I