OpenUI Forge — OpenAI
SkillAI & modelsOpenUI generative UI with OpenAI SDK backend. Streaming chat completions with gpt-5.5 (or any current OpenAI-compatible model).
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the OpenUI Forge — OpenAI skill
What this skill tells your AI
The instructions your AI receives, as published by othmanadi/openui-forge in skills/openui-forge-openai/SKILL.md and read by ahel’s review.
Build generative UI apps with OpenUI + OpenAI SDK. One backend, one adapter, streaming out of the box.
Activation Triggers
- "openui openai", "openui gpt", "openui chatgpt"
- "generative ui openai", "openai streaming ui"
Prerequisites
- Node.js >= 22 (24 LTS recommended), React >= 18.3.1 (19+ recommended)
OPENAI_API_KEYenvironment variable set- Optional:
OPENAI_BASE_URLto route via an OpenAI-compatible provider (Gemini, OpenRouter, xAI, DeepSeek, etc.) without code changes.OPENAI_BASE_URLis the correct env var; the legacyOPENAI_API_BASEwas removed in openai v6. See Provider Routing below. - Optional:
OPENAI_MODELto pin a specific model (defaults togpt-5.5) - Next.js project (App Router recommended)
Provider Routing
This is the OpenAI-compatible variant: the same OpenAI client and chat.completions.create code talks to any provider below by setting OPENAI_BASE_URL (and OPENAI_MODEL). No code changes. OPENAI_BASE_URL is the correct env var; the old OPENAI_API_BASE was removed in openai v6.
| Provider | OPENAI_BASE_URL | Example OPENAI_MODEL |
|---|---|---|
| Gemini | https://generativelanguage.googleapis.com/v1beta/openai/ | gemini-3.5-flash |
| OpenRouter | https://openrouter.ai/api/v1 | anthropic/claude-opus-4.7 |
| xAI (Grok) | https://api.x.ai/v1 | grok-4.3 |
| DeepSeek | https://api.deepseek.com | deepseek-v4-pro |
| Groq | https://api.groq.com/openai/v1 | llama-3.3-70b-versatile |
| Mistral | https://api.mistral.ai/v1 | mistral-large-latest |
| Together | https://api.together.ai/v1 | openai/gpt-oss-20b |
| Fireworks | https://api.fireworks.ai/inference/v1 | accounts/fireworks/models/glm-5 |
| Ollama (local) | http://localhost:11434/v1/ | llama3.3 (any placeholder API key) |
| LM Studio (local) | http://localhost:1234/v1 | loaded model id (any placeholder API key) |
Model ids drift; check each provider's current catalog. Base-url routing covers chat completions only, not full OpenAI API parity.
Azure OpenAI is not a generic drop-in. Use
OPENAI_BASE_URL=https://YOUR-RESOURCE.openai.azure.com/openai/v1/, setOPENAI_MODELto your deployment name (not a catalog id likegpt-5.5), and prefer theAzureOpenAIclient. The legacy data-plane path also needs an?api-version=query param.
Quick Start
- Install dependencies:
npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod openai
- Add the CSS import to
app/layout.tsx:
import "@openuidev/react-ui/components.css";
- Create the API route (Step 4 below)
- Create the frontend page (Step 5 below)
- Run
npm run devand test
Full Code
Backend: app/api/chat/route.ts
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import OpenAI from "openai";
const client = new OpenAI();
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.",
additionalRules: ["Always use Stack as root when combining multiple components."],
});
const response = await client.chat.completions.create({
model: process.env.OPENAI_MODEL ?? "gpt-5.5",
stream: true,
messages: [{ role: "system", content: systemPrompt }, ...messages],
});
// response.toReadableStream() produces NDJSON (one JSON object per line, no SSE `data:` prefix).
// Pair with openAIReadableStreamAdapter() on the frontend.
return new Response(response.toReadableStream(), {
headers: { "Content-Type": "application/x-ndjson" },
});
}
Frontend: app/chat/page.tsx
"use client";
import { FullScreen } from "@openuidev/react-ui";
import { openuiChatLibrary } from "@openuidev/react-ui/genui-lib";
import {
openAIReadableStreamAdapter,
openAIMessageFormat,
} from "@openuidev/react-headless";
export default function ChatPage() {
return (
<FullScreen
componentLibrary={openuiChatLibrary}
streamProtocol={openAIReadableStreamAdapter()}
messageFormat={openAIMessageFormat}
apiUrl="/api/chat"
/>
);
}
Component Creation
import { defineComponent } from "@openuidev/react-lang";
import { z } from "zod";
export const MyCard = defineComponent({
name: "MyCard",
description: "A card displaying a title and body text",
props: z.object({
title: z.string().describe("The card heading"),
body: z.string().describe("The card body content"),
}),
component: ({ props }) => (
<div style={{ border: "1px solid #ddd", borderRadius: 8, padding: 16 }}>
<h3>{props.title}</h3>
<p>{props.body}</p>
</div>
),
});
Add to a custom library with createLibrary([MyCard, ...others]) or use the built-in openuiLibrary.
System Prompt Generation
For runtime generation (used in the route above), call library.prompt(). For a static file:
npx @openuidev/cli generate ./src/lib/library.ts --out src/generated/system-prompt.txt
Validation Checklist
-
OPENAI_API_KEYis set in.env.local - CSS import present in root layout
- API route returns
response.toReadableStream()withapplication/x-ndjsoncontent type - Frontend uses
streamProtocol={openAIReadableStreamAdapter()}andopenAIMessageFormat -
componentLibrary={openuiChatLibrary}prop passed toFullScreen - React >= 18.3.1 installed (peer accepts
^18.3.1 || ^19.0.0)
Error Patterns
| Error | Cause | Fix |
|---|---|---|
| 401 from OpenAI | Missing or invalid API key | Set OPENAI_API_KEY in .env.local |
| Stream hangs | Missing toReadableStream() call | Ensure stream: true and return response.toReadableStream() |
| Components render as text | Library not passed to FullScreen | Add componentLibrary={openuiChatLibrary} prop |
| Blank screen | CSS not imported | Add @openuidev/react-ui/components.css to root layout |
| Nothing renders, no error | Wrong prop name (adapter is silently ignored) | Rename to streamProtocol and call the adapter as a function: streamProtocol={openAIReadableStreamAdapter()} |
| Partial render then stop | Model finished mid-output | Check token limits, increase max_tokens if needed |
Signals
- GitHub stars
- 22
- Last commit
- Aug 2026
ahel review
S4info
community integration — published by othmanadi, not openai
Automated review, not a security audit. Ruleset v1.
Advanced
- Catalog kind
- skill
- Gateway key
openui-forge-openai- Source
- github.com/othmanadi/openui-forge