Build a Generative UI Chat App

Build an AI chat app that responds with interactive UI components, not plain text.

Introduction

30 Second Summary

When you chat with an AI, it usually responds with plain text. What if it could respond with buttons, cards, tables, and forms instead?

In this project, you will build a full-screen AI chat app where the model responds with interactive React components that stream into the conversation in real time. You will also create your own custom component that the AI learns to use on demand.

What You'll Build

A streaming Generative UI chat application powered by OpenUI and OpenAI, where the AI composes rich UI components like cards, tables, and forms instead of plain markdown.

By the end of this project, you'll have:

  • A scaffolded Next.js app with OpenUI Chat pre-configured for streaming and component rendering.
  • A working backend API route that streams OpenUI Lang from OpenAI to render interactive UI.
  • A custom ProductCard component defined with Zod schemas and React, registered in your component library.
  • Secret Mission: add a ReviewCard component with star ratings and wire it into the library so the AI can display product reviews.

Are there any prerequisites?

You should be familiar with React and Next.js basics. You also need an OpenAI API key from platform.openai.com.

Scaffold the OpenUI Chat App

Before you can chat with an AI that composes interactive UI, you need a project wired up with streaming adapters, component renderers, and a backend API route.

The OpenUI CLI scaffolds a complete Next.js project with all of this pre-configured. In this step, you will scaffold the app, add your OpenAI API key, and confirm the built-in components stream correctly.

In this step, get ready to:
  • Scaffold a Next.js chat app using the OpenUI CLI.
  • Configure your OpenAI API key in a .env file.
  • Start the development server and test the built-in UI components.
Run the OpenUI CLI to scaffold a new project

The OpenUI CLI creates a full project structure with chat layouts, streaming adapters, a built-in component library, and an API route for OpenAI. One command gives you a working app.

  • Open your terminal.
  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal (macOS) or PowerShell (Windows) and press Enter to open it.
  • Move to your Desktop by running this command:
cd ~/Desktop
  • Scaffold your new project by running this command:
npx @openuidev/cli@latest create --name genui-chat-app --no-skill

What does this command do?

This runs the OpenUI scaffolding tool via npx without installing it globally.

  • --name genui-chat-app sets the project folder name.
  • --no-skill skips installing the optional AI coding agent skill, which you do not need for this project.

npx asks to install a package?

If npx displays "Need to install the following packages", type y and press Enter to continue. This is normal for first-time use.

The CLI will download the template, install dependencies, and generate a system prompt. This may take a minute or two.

  • Confirm the project folder was created by running:
ls

You should see genui-chat-app in the output.

Don't see genui-chat-app?

  • Make sure you ran the command from your Desktop directory. Run pwd to check your current location.
  • Check for error messages in the terminal output. Network issues or an outdated Node.js version can cause the scaffold to fail.

Still stuck? Help me troubleshoot the OpenUI CLI scaffold command.

  • Move into your new project directory by running:
cd genui-chat-app
Add your OpenAI API key

The backend API route needs your OpenAI API key to send requests to the model. You store this key in a .env file in the project root so Next.js can read it at runtime.

  • Create a .env file with your API key by running this command:
echo "OPENAI_API_KEY=sk-your-key-here" > .env
  • Replace sk-your-key-here with your actual OpenAI API key from platform.openai.com before pressing Enter.

What is a .env file?

A .env file stores environment variables that your app reads at startup. Next.js automatically loads this file so your API route can access OPENAI_API_KEY without hardcoding it in your source code.

  • Verify the file was created correctly by running:
cat .env

You should see OPENAI_API_KEY= followed by your actual API key.

File is empty or shows the wrong key?

  • If the file is empty, try creating it manually in your code editor instead. Create a new file called .env in the genui-chat-app folder and paste OPENAI_API_KEY= followed by your key.
  • Make sure there are no extra spaces around the = sign.

Need help? Help me set up my .env file with the OpenAI API key.

✔️ Awesome, I've got everything!

Great. Make sure you have saved your .env file before moving on.

ⓧ I'd like to double check the full code

Here is the complete .env file. Make sure yours matches this format, with your own API key replacing the placeholder.

OPENAI_API_KEY=sk-your-key-here
Start the development server and test the built-in components

Everything is wired up. Time to start the app and see the AI respond with interactive UI components instead of plain text.

  • Start the development server by running:
npm run dev

What does this command do?

The dev script first regenerates the system prompt from your component library, then starts the Next.js development server. The system prompt tells the LLM which UI components it is allowed to emit.

You should see output in your terminal indicating the server is ready on http://localhost:3000.

  • Open your browser.
  • Navigate to http://localhost:3000.

You should see a full-screen chat interface with a message input at the bottom.

  • Type a message like Build a pricing comparison table for three SaaS plans and press Enter.

Watch the AI respond with structured UI components that stream into the chat progressively. You should see a formatted table or card layout instead of plain markdown text.

  • Try another prompt like Create a sign-up form with name and email fields to see a different component type.

Why OpenUI Lang instead of JSON?

OpenUI Lang is a line-oriented format designed specifically for streaming UI generation. Each line can be parsed and rendered independently as it arrives from the model.

JSON requires waiting for a complete object before parsing. OpenUI Lang uses up to 67% fewer tokens than equivalent JSON, making it faster and cheaper to stream.

Not seeing UI components in the chat?

  • Check your terminal for error messages. A common cause is an invalid or missing API key in .env.
  • Make sure .env is in the project root (the genui-chat-app folder), not inside src/.
  • If you updated your .env file after starting the server, stop the server with Ctrl+C and run npm run dev again. Environment variables are only loaded at startup.

Still stuck? Help me debug my OpenUI chat app.

Your app is up and running with the built-in component library. Next up, you will explore the project structure to understand how the two-sided architecture works before adding your own custom component.

Explore the Project Structure and Architecture

Your chat app is up and running. You've already watched the AI compose interactive components in real time instead of plain text.

How does the AI know which components are available and how to render them? In this step, you'll explore the scaffolded project to uncover OpenUI's two-sided architecture.

In this step, get ready to:
  • Examine the key files in the scaffolded project.
  • Understand the two-sided OpenUI architecture.
  • Test the built-in components with different chat prompts.
Walk through the generated project files

The OpenUI CLI generated a Next.js project with four key files that work together to form a Generative UI pipeline. Two files handle the backend (telling the LLM what to generate), and two handle the frontend (rendering the output).

  • Open the genui-chat-app folder in your code editor.
  • In the file explorer sidebar, expand the src folder and locate these four files:
  • src/app/page.tsx is the frontend entry point. It renders the FullScreen chat layout with openuiChatLibrary as the component library and openAIAdapter() for streaming.
  • src/app/api/chat/route.ts is the backend API route. It loads the generated system prompt and sends it to OpenAI alongside your messages.
  • src/library.ts is the component library entrypoint. The openui generate CLI reads this file to produce the system prompt.
  • src/generated/system-prompt.txt is the auto-generated system prompt. It is created at build time and tells the LLM exactly which components it can use.

What is the two-sided architecture?

OpenUI splits the work across two sides. On the backend, the generated system prompt instructs the LLM about which components exist and how to use them. On the frontend, the component library tells React how to render whatever the LLM produces.

Both sides must stay in sync. If the system prompt describes a component that the frontend library doesn't know about, the UI falls back to plain text.

Read the auto-generated system prompt

The system prompt is the instruction manual the LLM reads before it responds to any message. Understanding what's in it helps you see how new components get wired up later.

  • Open src/generated/system-prompt.txt in your editor and skim through it.

You'll see three main sections inside this file.

  • OpenUI Lang syntax rules teach the LLM how to write in OpenUI's markup format instead of JSON or Markdown.
  • Component signatures list every component the LLM is allowed to use, along with their props and types.
  • Streaming guidelines tell the LLM how to structure its output so each line can be parsed and rendered progressively as it arrives.

Why OpenUI Lang instead of JSON?

OpenUI Lang is a line-oriented format purpose-built for streaming UI generation. Each line follows a simple identifier = Expression pattern, so the frontend can parse and render it as each line arrives.

JSON requires waiting for a complete object before parsing. OpenUI Lang is up to 67% more token-efficient than JSON for equivalent UI output. Fewer tokens means faster responses and lower API costs.

Test the built-in components with different prompts

Now that you know what's happening behind the scenes, put the built-in component library to work. The goal is to see how different prompts produce different UI components.

  • Switch to the browser tab with your chat app at http://localhost:3000.
  • Type this prompt into the chat: Build a pricing comparison table for three SaaS plans.
  • Watch the response stream in. You should see a structured table component with rows and columns, not a block of Markdown text.
  • Try another prompt: Create a sign-up form with name and email fields.
  • Notice how the AI responds with interactive form elements instead of static text. Each prompt triggers different components from the built-in library.

What is happening during streaming?

When you send a message, the backend API route forwards your prompt (plus the system prompt) to OpenAI. The LLM responds line by line in OpenUI Lang. As each line arrives, the frontend Renderer parses it and renders the matching React component immediately.

That's why you see components appear progressively instead of all at once. The streaming is real, not a loading animation.

Seeing plain text instead of components?

Make sure your dev server is still running in the terminal. If it stopped, restart it with npm run dev.

Check your .env file to confirm your OpenAI API key is correct. An invalid key causes the API route to fail silently.

If you're still stuck, help me debug why my OpenUI chat app is showing plain text instead of UI components.

You now understand how the pieces fit together. The system prompt teaches the LLM which components to write, and the component library teaches the frontend how to render them. Next up, you'll build your own custom component and plug it into this pipeline.

Define a Custom ProductCard Component

In the last step, you explored how OpenUI's two-sided architecture works. The system prompt tells the LLM what components exist, and the component library on the frontend knows how to render them.

Now it's time to build your own component. You'll define a custom ProductCard that the AI can compose whenever someone asks about products or shopping.

In this step, get ready to:
  • Create a ProductCard component with a Zod schema and React renderer.
  • Register ProductCard in the component library.
  • Wire the extended library into the frontend chat layout.
Create the ProductCard component file

OpenUI components have two halves. The schema (defined with Zod) tells the LLM what props the component accepts. The renderer (a React function) turns those props into visible UI.

You'll combine both halves into a single file using defineComponent.

  • Create a components folder inside src/ and a ProductCard.tsx file inside it by running these commands:
mkdir -p src/components
touch src/components/ProductCard.tsx
  • Confirm the file was created by running:
ls src/components

You should see ProductCard.tsx in the output.

  • Open src/components/ProductCard.tsx in your editor and paste the following code:
import { defineComponent } from "@openuidev/react-lang";
import { z } from "zod/v4";

export const ProductCard = defineComponent({
  // The name the LLM uses to reference this component
  name: "ProductCard",
  // Tells the LLM when this component is appropriate
  description: "Displays a product with name, price, image, and a buy button.",
  // Zod schema defines the props the LLM can pass
  props: z.object({
    name: z.string(),
    price: z.number(),
    imageUrl: z.string().url().optional(),
    ctaLabel: z.string().optional(),
  }),
  // React renderer turns props into visible UI
  component: ({ props }) => (
    <div
      style={{
        border: "1px solid #e2e8f0",
        borderRadius: "12px",
        padding: "16px",
        maxWidth: "280px",
        fontFamily: "sans-serif",
      }}
    >
      {props.imageUrl && (
        <img
          src={props.imageUrl}
          alt={props.name}
          style={{
            width: "100%",
            borderRadius: "8px",
            marginBottom: "12px",
          }}
        />
      )}
      <h3 style={{ margin: "0 0 4px 0", fontSize: "18px" }}>{props.name}</h3>
      <p
        style={{
          margin: "0 0 12px 0",
          fontSize: "24px",
          fontWeight: "bold",
          color: "#2563eb",
        }}
      >
        ${props.price.toFixed(2)}
      </p>
      <button
        style={{
          backgroundColor: "#2563eb",
          color: "white",
          border: "none",
          borderRadius: "8px",
          padding: "10px 20px",
          cursor: "pointer",
          width: "100%",
          fontSize: "14px",
        }}
      >
        {props.ctaLabel ?? "Buy Now"}
      </button>
    </div>
  ),
});

What does this code do?

defineComponent creates a component with four fields that OpenUI needs:

  • name and description go into the system prompt so the LLM knows when to use this component.
  • props is a Zod schema that defines what data the LLM can pass in. Required props (name, price) come first, optional props (imageUrl, ctaLabel) come last. This order matters because it determines positional argument order in OpenUI Lang.
  • component is the React renderer. It receives the LLM's data as props and returns styled JSX with the product name, price in blue, and a "Buy Now" button.
  • Save ProductCard.tsx.

You won't see a change in the browser yet. The component needs to be registered in the library first.

Seeing a TypeScript error in your editor?

  • Make sure you imported z from "zod/v4", not "zod". OpenUI requires the /v4 import path.
  • Check that defineComponent is imported from "@openuidev/react-lang", not from any other package.
  • help me fix a TypeScript error in my ProductCard.tsx component

✔️ Awesome, I've got everything!

Make sure you've saved src/components/ProductCard.tsx before moving on.

ⓧ I'd like to double check the full code

import { defineComponent } from "@openuidev/react-lang";
import { z } from "zod/v4";

export const ProductCard = defineComponent({
  name: "ProductCard",
  description: "Displays a product with name, price, image, and a buy button.",
  props: z.object({
    name: z.string(),
    price: z.number(),
    imageUrl: z.string().url().optional(),
    ctaLabel: z.string().optional(),
  }),
  component: ({ props }) => (
    <div
      style={{
        border: "1px solid #e2e8f0",
        borderRadius: "12px",
        padding: "16px",
        maxWidth: "280px",
        fontFamily: "sans-serif",
      }}
    >
      {props.imageUrl && (
        <img
          src={props.imageUrl}
          alt={props.name}
          style={{
            width: "100%",
            borderRadius: "8px",
            marginBottom: "12px",
          }}
        />
      )}
      <h3 style={{ margin: "0 0 4px 0", fontSize: "18px" }}>{props.name}</h3>
      <p
        style={{
          margin: "0 0 12px 0",
          fontSize: "24px",
          fontWeight: "bold",
          color: "#2563eb",
        }}
      >
        ${props.price.toFixed(2)}
      </p>
      <button
        style={{
          backgroundColor: "#2563eb",
          color: "white",
          border: "none",
          borderRadius: "8px",
          padding: "10px 20px",
          cursor: "pointer",
          width: "100%",
          fontSize: "14px",
        }}
      >
        {props.ctaLabel ?? "Buy Now"}
      </button>
    </div>
  ),
});
Register ProductCard in the component library

Your ProductCard exists as a file, but the app doesn't know about it yet. The component library in src/library.ts is what connects your component to both the system prompt and the frontend renderer.

You'll extend the built-in chat library with your ProductCard and add a rule telling the LLM when to use it.

  • Open src/library.ts in your editor and replace its entire contents with the following code:
import { createLibrary } from "@openuidev/react-lang";
import {
  openuiChatLibrary,
  openuiChatPromptOptions,
} from "@openuidev/react-ui/genui-lib";
import { ProductCard } from "./components/ProductCard";

// Extend the built-in chat library with your custom component
export const library = createLibrary({
  root: openuiChatLibrary.root ?? "Card",
  componentGroups: openuiChatLibrary.componentGroups,
  components: [...Object.values(openuiChatLibrary.components), ProductCard],
});

// Add a rule so the LLM knows when to use ProductCard
export const promptOptions = {
  ...openuiChatPromptOptions,
  additionalRules: [
    ...(openuiChatPromptOptions.additionalRules ?? []),
    "Use ProductCard when the user asks about products, shopping, or items for sale.",
  ],
};

What does this code do?

  • createLibrary builds a new component library. It keeps all the built-in chat components (by spreading openuiChatLibrary.components) and adds your ProductCard at the end.
  • root is set to "Card", which is the default container for chat responses. Each AI response is wrapped in a Card.
  • additionalRules is an array of natural language instructions that get added to the system prompt. Your rule tells the LLM to reach for ProductCard when the user mentions products or shopping.

Why extend instead of replace?

The built-in openuiChatLibrary already includes useful components like tables, forms, section blocks, and follow-up prompts. By spreading Object.values(openuiChatLibrary.components) into your new library, you keep all of those and just add your custom components on top.

  • Save library.ts.

You won't see a change in the browser yet. The frontend still imports the old library. The next substep wires this new one in.

Seeing an import error for ProductCard?

  • Double check that the import path is "./components/ProductCard" (relative path, no file extension). This path is relative to src/library.ts.
  • Make sure you saved ProductCard.tsx in the previous substep. The file needs to exist at src/components/ProductCard.tsx.
  • help me fix an import error in library.ts

✔️ Awesome, I've got everything!

Make sure you've saved src/library.ts before moving on.

ⓧ I'd like to double check the full code

import { createLibrary } from "@openuidev/react-lang";
import {
  openuiChatLibrary,
  openuiChatPromptOptions,
} from "@openuidev/react-ui/genui-lib";
import { ProductCard } from "./components/ProductCard";

export const library = createLibrary({
  root: openuiChatLibrary.root ?? "Card",
  componentGroups: openuiChatLibrary.componentGroups,
  components: [...Object.values(openuiChatLibrary.components), ProductCard],
});

export const promptOptions = {
  ...openuiChatPromptOptions,
  additionalRules: [
    ...(openuiChatPromptOptions.additionalRules ?? []),
    "Use ProductCard when the user asks about products, shopping, or items for sale.",
  ],
};
Wire the extended library into the frontend

The frontend chat layout still uses the default openuiChatLibrary. You need to swap it for your extended library so the FullScreen component knows how to render your ProductCard.

  • Open src/app/page.tsx in your editor.
  • Near the top of the file, find the import line that includes openuiChatLibrary. It looks something like this:
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
  • Add a new import line directly below it that imports your extended library:
import { library } from "@/library";
  • Now scroll down to the FullScreen component and find the componentLibrary prop. It currently looks like this:
componentLibrary={openuiChatLibrary}
  • Replace openuiChatLibrary with library, so the line now looks like this:
componentLibrary={library}

Why does this matter?

This is the frontend half of OpenUI's two-sided architecture. The componentLibrary prop tells the FullScreen renderer which components it can render.

Without this change, the LLM might generate OpenUI Lang referencing ProductCard, but the frontend wouldn't know how to render it. The response would fall back to plain text.

  • Save page.tsx.
  • Check your browser at http://localhost:3000. The chat interface should still load without errors.

The app looks the same for now. Your ProductCard is registered on the frontend, but the system prompt hasn't been regenerated yet. The LLM doesn't know about your new component until you do that in the next step.

App not loading or showing errors?

  • Check the terminal running your dev server for error messages. A common cause is a mismatched import path. The import should be "@/library" (using the @ alias that Next.js sets up for src/).
  • Make sure you only changed the componentLibrary prop value. Leave the other props on FullScreen (like streamProtocol and processMessage) untouched.
  • help me fix an error in my page.tsx after updating the component library

Your custom ProductCard is defined, registered, and wired into the frontend. Next up, you'll regenerate the system prompt so the LLM discovers your component and test the full loop from user prompt to rendered UI.

Regenerate the System Prompt and Test

Your custom ProductCard component is defined, your library is extended, and your page is wired up. There is one piece missing.

The system prompt is what tells the LLM which components it can use. The current prompt was generated before you added ProductCard, so the LLM has no idea your component exists. In this step, you will regenerate the prompt and test the full loop.

In this step, get ready to:
  • Regenerate the system prompt using the OpenUI CLI.
  • Restart the dev server and test your custom ProductCard in the chat.
  • Verify ProductCard appears in the generated system prompt file.
Regenerate the system prompt

The system prompt teaches the LLM about every component in your library. It includes component names, prop schemas, and usage rules. Since the current prompt was generated before you added ProductCard, the LLM cannot use it yet.

  • Regenerate the system prompt by running this command:
npx @openuidev/cli@latest generate src/library.ts --out src/generated/system-prompt.txt

What does this command do?

The OpenUI CLI reads your src/library.ts file and inspects every component registered in the library.

It produces a system prompt that describes each component's name, props, and types in OpenUI Lang syntax. The output is written to src/generated/system-prompt.txt, which the backend API route sends to OpenAI alongside user messages.

  • You should see output confirming the prompt was written to src/generated/system-prompt.txt.

Seeing an error?

  • Make sure you are running the command from inside the genui-chat-app folder.
  • Check that src/library.ts exports a valid library created with createLibrary. A syntax error in this file causes the generate command to fail.
  • Help me debug this system prompt generation error.
Restart the dev server and test your ProductCard

The dev server cached the old system prompt when it started. Restarting it picks up the newly regenerated prompt so the LLM can see your ProductCard component.

  • Stop the dev server by pressing Ctrl+C in your terminal.
  • Start it again by running:
npm run dev

The dev script auto-regenerates the prompt

The npm run dev script runs the prompt generation step before starting Next.js. You ran it manually in the previous substep to understand what happens under the hood.

Going forward, every time you restart the dev server, the system prompt auto-updates with any library changes you have made.

  • Open http://localhost:3000 in your browser.
  • Type this prompt into the chat:
Show me 3 products for a tech store: wireless headphones at $79.99, a mechanical keyboard at $149.99, and a USB-C hub at $39.99

The AI should respond with styled ProductCard components. Each card displays the product name, a blue price, and a "Buy Now" button.

What's happening behind the scenes?

Your message goes to the backend API route, which sends it to OpenAI along with the regenerated system prompt. OpenAI reads the prompt, sees ProductCard in the component signatures, and responds using OpenUI Lang syntax.

The frontend Renderer parses the OpenUI Lang stream line by line and renders your React components progressively as tokens arrive. This is why the UI feels like it streams in rather than appearing all at once.

Not seeing ProductCard components?

  • The AI might respond with generic cards instead of your custom ProductCard. Try being more explicit: "Use the ProductCard component to show me wireless headphones at $79.99."
  • If you see plain text instead of any UI components, check that src/app/page.tsx passes library (not openuiChatLibrary) as the componentLibrary prop.
  • Make sure your .env file has a valid OpenAI API key. An invalid key causes the API route to fail silently.
  • Why isn't my custom ProductCard component rendering in the chat?
Verify ProductCard in the system prompt

You have seen the component render in the chat. Now confirm the LLM actually knows about it by checking the generated prompt file directly.

  • Open src/generated/system-prompt.txt in your editor.
  • Search for ProductCard in the file.

You should find ProductCard listed in the component signatures section with its props: name (string, required), price (number, required), imageUrl (string url, optional), and ctaLabel (string, optional).

Why check the system prompt?

This confirms the full loop is working. The CLI read your component definition, extracted the Zod schema, and translated it into instructions the LLM can follow.

If ProductCard is missing from this file, the LLM will never use it no matter what you ask. The system prompt is the single source of truth for what components are available.

Secret mission

Add a ReviewCard Component

Your AI can show products, but what about customer reviews? In this mission, you will build a ReviewCard component with star ratings and wire it into the library so the AI can display reviews alongside your product cards.

Before you go

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs locally on your machine, so the only ongoing cost is OpenAI API usage when you send chat messages.

Cost warning

Your OpenAI API key is billed per request. Each chat message costs a fraction of a cent, but leaving the app open and sending many messages could add up over time. If you are done testing, stop the dev server to prevent accidental API calls.

Resources you used:

  • The genui-chat-app project folder on your Desktop.
  • A .env file containing your OpenAI API key.
  • Your OpenAI API key (from platform.openai.com).
  • The Next.js development server (running on http://localhost:3000).

Keep everything running

No action needed. Choose this if you are still actively building or want to keep experimenting with new components and prompts.

  • Your dev server stays running on http://localhost:3000.
  • Your .env file and OpenAI API key remain in place.
  • Keep an eye on your OpenAI usage dashboard at platform.openai.com to monitor spending.

Pause - I'll come back to this later

Stop the dev server to free up your terminal and prevent any accidental API calls. Your project files stay on disk so you can pick up where you left off.

  • In your terminal, press Ctrl+C to stop the Next.js dev server.
  • Your genui-chat-app folder and all project files remain on your Desktop.
  • To resume later, open a terminal in the genui-chat-app folder and run npm run dev.

Delete - I don't want to use this again

Remove all project files from your machine. Your OpenAI API key will still exist on your OpenAI account unless you revoke it separately.

  • In your terminal, press Ctrl+C to stop the dev server if it is still running.
  • Delete the genui-chat-app folder from your Desktop.
  • If you created the OpenAI API key only for this project, go to platform.openai.com, navigate to API keys, and revoke the key.

Mission accomplished

Nice Work!

You just built a Generative UI chat app from scratch. Instead of plain text responses, your AI composes and streams interactive React components in real time.

You learned how to:

  • Scaffolded a Next.js app with OpenUI Chat and explored the two-sided architecture where a generated system prompt instructs the LLM on the backend and a component library renders the output on the frontend.
  • Defined a custom ProductCard component using Zod schemas and a React renderer, then extended the built-in library so the LLM can generate it on demand.
  • Tested the full Generative UI streaming loop: user prompt to OpenUI Lang generation to interactive UI components rendered in real time.
  • Secret Mission: Built a ReviewCard component with star ratings and wired it into your component library.

Ready to quiz yourself?