.codex/skills/openui-forge-rust/SKILL.md
OpenUI generative UI with Rust Axum backend. Async SSE streaming with reqwest and async-stream.
npx skillsauth add OthmanAdi/openui-forge openui-forge-rustInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build generative UI apps with a React frontend + Rust Axum backend. Async SSE streaming to OpenAI-compatible NDJSON.
OPENAI_API_KEY environment variable setnpm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
cargo run on :3001, frontend on :3000backend/Cargo.toml[package]
name = "openui-backend"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["stream"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
async-stream = "0.3"
futures = "0.3"
tower-http = { version = "0.5", features = ["cors"] }
dotenvy = "0.15"
backend/src/main.rsuse axum::{extract::Json, response::sse::{Event, Sse}, routing::post, Router};
use futures::stream::Stream;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::{convert::Infallible, fs, net::SocketAddr};
use tower_http::cors::{Any, CorsLayer};
#[derive(Deserialize)]
struct ChatRequest {
messages: Vec<Message>,
}
#[derive(Serialize, Deserialize, Clone)]
struct Message {
role: String,
content: String,
}
static mut SYSTEM_PROMPT: String = String::new();
#[tokio::main]
async fn main() {
dotenvy::dotenv().ok();
let prompt = fs::read_to_string("system-prompt.txt")
.expect("system-prompt.txt not found");
unsafe { SYSTEM_PROMPT = prompt; }
let cors = CorsLayer::new()
.allow_origin("http://localhost:3000".parse::<http::HeaderValue>().unwrap())
.allow_methods([http::Method::POST])
.allow_headers(Any);
let app = Router::new()
.route("/api/chat", post(chat_handler))
.layer(cors);
let addr = SocketAddr::from(([0, 0, 0, 0], 3001));
println!("Rust backend listening on {addr}");
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn chat_handler(
Json(req): Json<ChatRequest>,
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
let system_prompt = unsafe { SYSTEM_PROMPT.clone() };
let mut messages = vec![Message { role: "system".into(), content: system_prompt }];
messages.extend(req.messages);
let api_key = std::env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set");
let client = Client::new();
let stream = async_stream::stream! {
let resp = client
.post("https://api.openai.com/v1/chat/completions")
.bearer_auth(&api_key)
.json(&serde_json::json!({
"model": "gpt-4o",
"stream": true,
"messages": messages,
}))
.send()
.await;
if let Ok(resp) = resp {
let mut bytes_stream = resp.bytes_stream();
use futures::StreamExt;
let mut buffer = String::new();
while let Some(Ok(chunk)) = bytes_stream.next().await {
buffer.push_str(&String::from_utf8_lossy(&chunk));
while let Some(pos) = buffer.find("\n\n") {
let line = buffer[..pos].to_string();
buffer = buffer[pos + 2..].to_string();
if line.starts_with("data: ") {
yield Ok(Event::default().data(&line[6..]));
}
}
}
}
};
Sse::new(stream)
}
app/chat/page.tsx"use client";
import { FullScreen } from "@openuidev/react-ui";
import { openuiLibrary } from "@openuidev/react-ui";
import {
openAIReadableStreamAdapter,
openAIMessageFormat,
} from "@openuidev/react-headless";
export default function ChatPage() {
return (
<FullScreen
componentLibrary={openuiLibrary}
adapter={openAIReadableStreamAdapter}
messageFormat={openAIMessageFormat}
apiUrl="http://localhost:3001/api/chat"
/>
);
}
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
system-prompt.txt exists in the Rust backend directoryOPENAI_API_KEY is set in environment or .envapiUrl points to http://localhost:3001/api/chatopenAIReadableStreamAdapter and openAIMessageFormat| Error | Cause | Fix |
|-------|-------|-----|
| system-prompt.txt not found | File missing | Run CLI generate command |
| CORS blocked | Origin not in CorsLayer | Update .allow_origin() |
| Partial SSE events | Chunk boundary splitting | Buffer and split on \n\n boundaries (handled in code) |
| Compile error on http::HeaderValue | Missing http crate | tower-http re-exports it, or add http = "1" to deps |
| Connection reset | Tokio runtime panic | Check .await on all async calls, verify features = ["full"] |
development
Build generative UI with OpenUI — any LLM provider, any backend language. Scaffold, integrate, validate.
data-ai
使用 OpenUI 构建生成式 UI 应用 — 支持任意 LLM 提供商、任意后端语言。脚手架、集成、验证。
tools
OpenUI generative UI with Vercel AI SDK. streamText, toUIMessageStreamResponse, and tools support.
development
OpenUI generative UI with Rust Axum backend. Async SSE streaming with reqwest and async-stream.