14k

Introduction

json-render is a framework for Generative UI — AI-generated interfaces that are safe, predictable, and render natively on any platform.

What is Generative UI?#

Most AI integrations treat the interface as fixed. Developers build layouts ahead of time, and AI fills in the data — a chatbot response, a summary, a recommendation. The UI itself never changes.

Generative UI is different. The AI generates the interface itself: which components to show, how to arrange them, what data to bind, what actions to wire up. Every response can produce a unique, purpose-built UI tailored to the user's request.

The challenge is that unconstrained AI output is unpredictable. It can hallucinate component names, produce invalid structures, or generate unsafe code. You need a way to let AI be creative with layout and composition while keeping it within boundaries you control.

That is what json-render does. You define a catalog of components and actions. AI generates JSON constrained to that catalog. Your components render the result natively — on web or mobile — with full type safety and no arbitrary code execution.

How json-render Works#

1. Define your catalog#

A catalog declares what AI can use: components with typed props, actions with typed params.

import { defineCatalog } from '@json-render/core';
import { schema } from '@json-render/react/schema';
import { z } from 'zod';

export const catalog = defineCatalog(schema, {
  components: {
    Card: {
      props: z.object({ title: z.string() }),
      slots: ["default"],
    },
    Metric: {
      props: z.object({
        label: z.string(),
        value: z.string(),
      }),
    },
  },
});

2. AI generates a spec#

Given a prompt like "show me a revenue dashboard", AI outputs a JSON spec — a flat tree of elements constrained to your catalog:

{
  "root": "card-1",
  "elements": {
    "card-1": {
      "type": "Card",
      "props": { "title": "Revenue Dashboard" },
      "children": ["metric-1", "metric-2"]
    },
    "metric-1": {
      "type": "Metric",
      "props": { "label": "Total Revenue", "value": "$48,200" }
    },
    "metric-2": {
      "type": "Metric",
      "props": { "label": "Growth", "value": "+12%" }
    }
  }
}

3. Your components render it#

Map catalog types to real components with a registry, then render the spec:

import { Renderer, StateProvider, VisibilityProvider } from '@json-render/react';

<StateProvider initialState={{}}>
  <VisibilityProvider>
    <Renderer spec={spec} registry={registry} />
  </VisibilityProvider>
</StateProvider>

The result is a native UI built from your own components — not an iframe, not markdown, not generated code. The AI chose the structure; you control everything else.

Key Concepts#

  • Catalog — Define the components, actions, and validation functions AI can use. This is the contract between your app and the AI.
  • Registry — Map catalog types to platform-specific implementations. React components on web, React Native views on mobile.
  • Specs — The JSON output AI generates. A flat tree of typed elements with props, children, data bindings, and visibility conditions.
  • Streaming — Render progressively as the AI responds. Each JSONL patch adds to the spec and the UI updates in real time.
  • Data Binding — Bind props to runtime data with $state paths, repeat elements over arrays, and wire two-way input bindings.
  • Visibility — Show or hide elements based on state conditions. The AI can generate conditional UIs without writing logic.
  • Generation Modes — Standalone mode for full-page generated UI or inline mode for UI embedded in a conversation.

Next#