OpenUI

Overview

Understand the language, prompt, parser, and renderer that turn model output into application UI.

OpenUI Lang is the contract between a model and your application. You define the components the model may use, generate instructions from those definitions, and stream the model's OpenUI Lang response into a renderer.

Four pieces make that flow work:

  • Component library: Your Zod schemas and framework components define what the model can use and how each element behaves in your application.
  • System prompt: The prompt generator turns that library into component signatures, language rules, examples, and streaming instructions for the model.
  • Parser: The streaming parser turns OpenUI Lang into a typed element tree, validates component usage, and handles partial output while tokens arrive.
  • Renderer: The renderer maps the parsed tree to your components so the result uses your design system and application behavior.

@X(...) is either a function, which computes a value, or an action, which runs on click. The name decides which. For example, @Count(open) in TextContent("Open: " + @Count(open)) is a function, and @ToAssistant("Explain this") in Button("Explain", @ToAssistant("Explain this")) is an action.

The core loop

  1. Define the components your application supports.
  2. Generate model instructions from those definitions.
  3. Send the instructions and conversation to a model provider or route through Gateway for reliability.
  4. Stream the resulting OpenUI Lang into the renderer.
  5. Handle component interactions with application state, tools, queries, and mutations.

The language and renderer do not depend on a model provider, chat library, or hosted service. The Gateway is the default in these docs because it adds streaming correction and provider fallbacks without changing the component contract in your application.

Example

OpenUI Lang (Token Efficient)
root = Stack([welcomeCard])
welcomeCard = Card([welcomeHeader, signupForm])
welcomeHeader = CardHeader("Welcome", "Get started with our platform")
signupForm = Form("signup", actions, [nameField, emailField])
nameField = FormControl("Name", Input("name", "Your name", "text", {required: true, minLength: 2}))
emailField = FormControl("Email", Input("email", "you@example.com", "email", {required: true, email: true}))
actions = Buttons([signUpBtn, learnMoreBtn], "row")
signUpBtn = Button("Sign up", @ToAssistant("Sign me up"), "primary")
learnMoreBtn = Button("Learn more", @ToAssistant("Tell me more about the platform"), "secondary")
Output Preview
Welcome
Get started with our platform

Continue with Defining Components, then read System Prompts and The Renderer.

On this page