0.x early · MIT licensed

Let AI agents answer with interfaces, not just text.

An agent emits a small declarative JSON document. A runtime validates it, and a renderer draws it with your own components. No HTML, CSS or JavaScript from the model, so there is nothing to execute.

$git clone https://github.com/Pranavtej/GenUI-Protocol.git && cd GenUI-Protocol && pnpm install && pnpm build
23
built-in components
2
renderers: React, Angular
13
MCP tools for agents
6
published JSON Schemas
Playground

A document in, an interface out

This is a miniature of what the renderers do: inputs bound to a data model, templates that update as you type, and a submit action that sends an event to the agent.

{
  "version": "1.0.0",
  "data": {
    "form": {
      "name": ""
    }
  },
  "root": {
    "t": "card",
    "p": {
      "title": "Sign up"
    },
    "c": [
      {
        "t": "input",
        "p": {
          "label": "Name",
          "value": {
            "$bind": "form.name"
          }
        }
      },
      {
        "t": "text",
        "p": {
          "content": {
            "$tpl": "Hello {{form.name}}"
          }
        }
      },
      {
        "t": "button",
        "p": {
          "label": "Send",
          "onClick": {
            "do": "submit",
            "name": "signup",
            "from": "form"
          }
        }
      }
    ]
  }
}
Sign up

Hello

How it works

Define, validate, render

01

Define or generate

An agent (or your code) emits a small declarative JSON document: nodes, data, bindings and actions. Build it with the JS or Python SDK, or let a model write it from the generated prompt.

build.ts
import { ui, bind, actions, document, assertValid } from "@genui-protocol/sdk-js";

assertValid(document(
  ui.card({ title: "Sign up" },
    ui.input({ label: "Name", value: bind("form.name") }),
    ui.button({ label: "Send", onClick: actions.submit("signup", "form") })),
  { form: { name: "" } },
));
02

Validate

The runtime enforces size and depth limits, URL checks, allow-lists and duplicate-id rules. Invalid documents fail with readable errors, so a validate-and-repair loop can fix them.

terminal
$ genui validate doc.json      # exit 1 + readable errors when invalid
$ genui prompt                 # LLM system prompt, generated from the registry
03

Render

A renderer draws the document with your own components. UI events flow back to the agent, which replies with RFC 6902 patches or sequenced stream frames.

App.tsx
import { GenUiRenderer, createSession } from "@genui-protocol/renderer-react";

const session = createSession({ document, onEmit: (event) => agent.send(event) });

<GenUiRenderer session={session} />;
What you get

A protocol, a hardened runtime, renderers and agent tooling

Nothing to execute

The model never writes HTML, CSS or JavaScript. It describes a document; your renderer decides how it looks.

Data binding and actions

$bind and $tpl expressions with two-way inputs, plus declarative actions: setData, toggle, navigate, emit and submit.

Patches and streaming

Atomic RFC 6902 patches, an id-keyed diff, and an ordered stream consumer that resyncs when it falls behind.

Agent tooling

An MCP server (stdio and REST/SSE), a prompt kit generated from the registry, JS and Python SDKs, a CLI, and genui-eval.

Your components

Theme through CSS variables, or register custom namespaced components alongside the 23 built-ins.

Conformance fixtures

Language-neutral test vectors for patches, validation, bindings, actions and rendering. TypeScript and Python both pass.

Components

23 built-in components

The same set is implemented by the React and Angular renderers. Agents discover them through the registry, so the prompt never goes stale.

Layout
pagesectiongridflexstackdashboard
General
cardtextheadingbuttontabs
Forms
inputtextareaselectcheckbox
Data
tablechartkpitimeline
Overlay
dialogdrawer
Workflows
workflowexecutionGraph
See it work

Recorded from the real apps

Every clip comes from the playground and example apps in the repository.

Edit JSON, watch it re-render
Edit JSON, watch it re-render
Change bar to line to pie. Break the document and the validator catches it.
Charts, KPIs and tables
Charts, KPIs and tables
One data model, updated in place by a stream of frames.
One document, two renderers
One document, two renderers
React and Angular draw the same document from the same stream.
Forms that talk to an agent
Forms that talk to an agent
Bound inputs, a submit action, and an agent reply that advances a workflow.
Status

Early, and honest about it

GenUI is 0.x. This is what exists today and what does not.

Implemented and tested
  • Protocol, spec and JSON Schemas
  • Validator, patches, streaming with resync
  • React and Angular renderers (all 23 components)
  • MCP server, JS and Python SDKs, CLI, prompt kit
  • Shared conformance fixtures
Not yet
  • Packages are not published to npm or PyPI yet
  • genui-eval has never run against a real model
  • Vue, Svelte, React Native, SwiftUI, Flutter renderers
  • Remote data sources, form validation rules, WebSocket transport

Want to help? Read CONTRIBUTING.md.