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';
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 — Generate standalone UI (playground/builder) or inline UI within a chat conversation.

Next