---
title: "OpenUI: A Framework for Rapid Generative UI Development"
description: "Implementing Generative UI from scratch means dealing with messy component management and streaming control. OpenUI is a framework that neatly abstracts and hides all of that."
lang: "en"
canonical: "https://llm-lab.dev/en/posts/generative-ui-fast-development-openui/"
source: "https://llm-lab.dev/en/posts/generative-ui-fast-development-openui.md"
publishedAt: "2026-04-21"
updatedAt: "2026-04-21"
category: "Generative UI"
tags:
  - "generative-ui"
  - "openui"
---

# OpenUI: A Framework for Rapid Generative UI Development

**Generative UI** — the technique where generative AI dynamically creates UIs for users — has been getting a lot of attention lately.
Implementing it from scratch means component management and streaming control become a huge pain, but I found a framework called **OpenUI** that neatly abstracts and generalizes all of that. Here are the points that caught my eye.



## What is OpenUI, exactly?

A lightweight framework specialized for implementing Generative UI.
It catches structured data (like json) returned from an AI (LLM) and nicely generalizes the process of dynamically mapping it to frontend components like React or Next.js.

### Key Benefits

* **Reduced Boilerplate:** You barely need any boilerplate code for streaming handling, loading state management, or dynamic component rendering.
* **Not Tied to a Specific LLM:** It can be flexibly combined with major providers like OpenAI, Anthropic (claude), or Gemini, as well as the Vercel AI SDK (the interface is abstracted).
* **Type Safety for UIs:** It makes it easy to define schemas (arguments and properties) for the generated UIs, and it seems to work well with TypeScript.



## How Does It Work? (The Flow)

The overall flow consists of three steps.

1. **Backend (AI Side):**
For a user request (e.g., "show me a progress graph"), the LLM performs a function call (tool calling / structured outputs) and generates and streams parameters (json) needed for screen rendering.
2. **OpenUI (Mediator):**
It parses the streaming data (incomplete json) and completed data in real time, mapping it into UI component states (props).
3. **Frontend (Rendering Side):**
Based on the component name and props passed from OpenUI, it dynamically maps and renders pre-prepared React components (e.g., `<ProgressBar/>` or `<Card/>`).

---

## Basic Implementation Overview

*Rough code notes for trying it out locally.

### 1. Registering UI Components in a Registry

Map the UIs (components) you want to generate to their identifiers beforehand.

```typescript
// Custom components you want to render
import { WeatherCard } from '@/components/WeatherCard';
import { StockChart } from '@/components/StockChart';

// Register with OpenUI: "when this name comes in, render this component"
export const uiRegistry = {
  weather: WeatherCard,
  stock: StockChart,
};

```

### 2. Rendering on the Frontend

By using components and hooks provided by OpenUI, you can express the "loading state" during streaming and the "gradual assembly of the UI" with minimal code.

```tsx
import { useGenerativeUI } from 'openui-framework-package'; // *use actual package name
import { uiRegistry } from './registry';

export default function ChatView() {
  // Feed the AI stream and output into OpenUI's hook
  const { uiElements, submitMessage } = useGenerativeUI({
    api: '/api/chat',
    registry: uiRegistry,
  });

  return (
    <div className="flex flex-col gap-4 p-4">
      {uiElements.map((element, index) => {
        // OpenUI parses the stream and automatically assigns the appropriate component
        return <element.Component key={index} {...element.props} />;
      })}
    </div>
  );
}

```

---

## Personal Highlights and Use Cases

> 💡 **When might you use it?**
> * **AI Agent Apps:** When you want to dynamically insert "forms," "task lists," or "graphs" into a chat UI based on user instructions.
> * **Improved UX:** When you want to show users the feeling of "UI being generated right now (a skeleton gradually filling with data)" during streaming, rather than waiting for the LLM output to completely finish.
> >
>

### Points I Want to Dig Deeper Into Next Time

* How to most smartly sync component prop type definitions (with zod, etc.) with LLM structured outputs schemas.
* Fallback behavior when a stream errors out midway.
