Build generative UI with OpenUI — any LLM provider, any backend language. Scaffold, integrate, validate.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
OpenUI generative UI with LangChain/LangGraph backend. Supports ChatOpenAI and ChatAnthropic.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Build generative UI apps with OpenUI + LangChain. Stream from ChatOpenAI or ChatAnthropic, convert to OpenAI NDJSON.
OPENAI_API_KEY or ANTHROPIC_API_KEY setnpm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod @langchain/openai @langchain/core
# For Anthropic: npm install @langchain/anthropic
app/layout.tsx:import "@openuidev/react-ui/components.css";
npm run dev and testapp/api/chat/route.tsimport { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage, SystemMessage, AIMessage } from "@langchain/core/messages";
const model = new ChatOpenAI({ model: process.env.OPENAI_MODEL ?? "gpt-5.5", streaming: true });
export async function POST(req: Request) {
const { messages } = await req.json();
const systemPrompt = openuiChatLibrary.prompt({
preamble: "You are a helpful assistant that generates interactive UIs.",
});
const lcMessages = [
new SystemMessage(systemPrompt),
...messages.map((m: { role: string; content: string }) =>
m.role === "user" ? new HumanMessage(m.content) : new AIMessage(m.content)
),
];
const stream = await model.stream(lcMessages);
const encoder = new TextEncoder();
const id = `chatcmpl-${Date.now()}`;
const readableStream = new ReadableStream({
async start(controller) {
for await (const chunk of stream) {
const text = typeof chunk.content === "string" ? chunk.content : "";
if (!text) continue;
const payload = {
id,
object: "chat.completion.chunk",
choices: [{ index: 0, delta: { content: text }, finish_reason: null }],
};
controller.enqueue(encoder.encode(`data: ${JSON.stringify(payload)}\n\n`));
}
const done = {
id,
object: "chat.completion.chunk",
choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
};
controller.enqueue(encoder.encode(`data: ${JSON.stringify(done)}\n\n`));
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
controller.close();
},
});
return new Response(readableStream, {
headers: { "Content-Type": "text/event-stream" },
});
}
app/api/chat/route.tsReplace the model initialization and import:
import { ChatAnthropic } from "@langchain/anthropic";
const model = new ChatAnthropic({
model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-6",
maxTokens: 4096,
streaming: true,
});
Everything else (message mapping, stream conversion, response) stays identical.
app/chat/page.tsx"use client";
import { FullScreen } from "@openuidev/react-ui";
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import {
openAIAdapter,
openAIMessageFormat,
} from "@openuidev/react-headless";
export default function ChatPage() {
return (
<FullScreen
componentLibrary={openuiChatLibrary}
streamProtocol={openAIAdapter()}
messageFormat={openAIMessageFormat}
apiUrl="/api/chat"
/>
);
}
The backend emits SSE (
data: {json}\n\n). Pair it withopenAIAdapter()on the frontend. (langGraphAdapteris also exported from@openuidev/react-headlessif you stream LangGraph events natively rather than converting to OpenAI shape.)
import { defineComponent } from "@openuidev/react-lang";
import { z } from "zod";
export const MetricCard = defineComponent({
name: "MetricCard",
description: "Displays a metric with label, value, and optional trend",
props: z.object({
label: z.string().describe("Metric name"),
value: z.number().describe("Current metric value"),
trend: z.enum(["up", "down", "flat"]).optional().describe("Trend direction"),
}),
component: ({ props }) => (
<div style={{ padding: 16, border: "1px solid #e5e7eb", borderRadius: 8 }}>
<div style={{ fontSize: 14, color: "#6b7280" }}>{props.label}</div>
<div style={{ fontSize: 24, fontWeight: 700 }}>{props.value}</div>
{props.trend && <span>{props.trend === "up" ? "+" : props.trend === "down" ? "-" : "="}</span>}
</div>
),
});
npx @openuidev/cli generate ./src/lib/library.ts --out src/generated/system-prompt.txt
@langchain/openai or @langchain/anthropic installeddata: prefixfinish_reason: "stop" and ends with data: [DONE]streamProtocol={openAIAdapter()} and openAIMessageFormat| Error | Cause | Fix |
|---|---|---|
| Empty chunks in stream | LangChain AIMessageChunk content may be empty | Skip chunks where text is empty |
| Type error on messages | Wrong LangChain message class | Map user to HumanMessage, assistant to AIMessage |
| Module not found | Missing LangChain provider package | Install @langchain/openai or @langchain/anthropic |
| Stream hangs | Missing [DONE] sentinel | Always send final stop chunk and [DONE] |
| CORS error | Cross-origin frontend | Add CORS headers if frontend/backend are split |
아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Build generative UI with OpenUI — any LLM provider, any backend language. Scaffold, integrate, validate.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
OpenUI generative UI with Anthropic Claude SDK backend. Stream conversion to OpenAI NDJSON format.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
OpenUI generative UI with C# ASP.NET Core Minimal API backend. Direct OpenAI API SSE streaming via HttpClient on .NET 10.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
OpenUI generative UI with Elixir Phoenix backend. Chunked SSE streaming via Plug.Conn and Req.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
OpenUI generative UI with Go (net/http) backend. Direct OpenAI API streaming via HTTP.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
OpenUI generative UI with a Java Spring Boot (WebFlux) backend. Streams the OpenAI API directly via WebClient as SSE.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.