openui-forge-rust
Generative UI development with Rust and React.
Install
mkdir -p .claude/skills/openui-forge-rust && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16559" && unzip -o skill.zip -d .claude/skills/openui-forge-rust && rm skill.zipInstalls to .claude/skills/openui-forge-rust
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
OpenUI generative UI with Rust Axum backend. Async SSE streaming with reqwest and async-stream.Key capabilities
- →Build generative UI applications
- →Set up a Rust Axum backend
- →Implement async SSE streaming
- →Generate system prompts for OpenAI-compatible NDJSON
- →Configure CORS for frontend-backend communication
- →Handle partial SSE lines across chunk boundaries
How it works
This skill provides code examples and instructions for setting up a React frontend and a Rust Axum backend that uses `reqwest` and `async-stream` for async SSE streaming to OpenAI-compatible NDJSON, including system prompt generation and CORS configuration.
Inputs & outputs
When to use openui-forge-rust
- →Creating generative UI
- →Setting up Rust backend
- →Streaming UI updates
About this skill
OpenUI Forge — Rust
Build generative UI apps with a React frontend + Rust Axum backend. Async SSE streaming to OpenAI-compatible NDJSON.
Activation Triggers
- "openui rust", "openui axum", "openui rust backend"
- "generative ui rust", "rust streaming ui backend"
Prerequisites
- Node.js >= 22 (24 LTS recommended) + React >= 18.3.1 (19+ recommended) (frontend)
- Rust >= 1.75 with Cargo (backend)
OPENAI_API_KEYenvironment variable set
Quick Start
- Create the React frontend and install OpenUI deps:
npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod
- Generate the system prompt:
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
- Create the Rust backend (see Full Code below)
- Run:
cargo runon:3001, frontend on:3000
Full Code
Backend: backend/Cargo.toml
[package]
name = "openui-backend"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = "0.8"
http = "1"
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.13", features = ["json", "stream"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
async-stream = "0.3"
futures = "0.3"
tower-http = { version = "0.6", features = ["cors"] }
dotenvy = "0.15"
Backend: backend/src/main.rs
use axum::{
extract::{Json, State},
response::sse::{Event, Sse},
routing::post,
Router,
};
use futures::stream::Stream;
use http::HeaderValue;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::{convert::Infallible, fs, net::SocketAddr, sync::Arc};
use tower_http::cors::{Any, CorsLayer};
#[derive(Deserialize)]
struct ChatRequest {
messages: Vec<Message>,
}
#[derive(Serialize, Deserialize, Clone)]
struct Message {
role: String,
content: String,
}
#[derive(Clone)]
struct AppState {
system_prompt: String,
}
#[tokio::main]
async fn main() {
dotenvy::dotenv().ok();
let system_prompt = fs::read_to_string("system-prompt.txt")
.expect("system-prompt.txt not found");
let state = Arc::new(AppState { system_prompt });
let cors = CorsLayer::new()
.allow_origin("http://localhost:3000".parse::<HeaderValue>().unwrap())
.allow_methods([http::Method::POST])
.allow_headers(Any);
let app = Router::new()
.route("/api/chat", post(chat_handler))
.layer(cors)
.with_state(state);
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(
State(state): State<Arc<AppState>>,
Json(req): Json<ChatRequest>,
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
let mut messages = vec![Message { role: "system".into(), content: state.system_prompt.clone() }];
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": std::env::var("OPENAI_MODEL").unwrap_or_else(|_| "gpt-5.5".into()),
"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)
}
Frontend: 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="http://localhost:3001/api/chat"
/>
);
}
The Rust backend re-emits SSE via Axum's
Sse<...>response (Axum wraps eachEvent::default().data(...)with thedata:prefix). Pair it withopenAIAdapter()on the frontend.openAIReadableStreamAdapter()is for NDJSON and will silently produce no output here.
System Prompt Generation
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
Validation Checklist
-
system-prompt.txtexists in the Rust backend directory -
OPENAI_API_KEYis set in environment or.env - CORS layer allows the frontend origin
- SSE events forward OpenAI stream chunks correctly
- Buffer parsing handles partial SSE lines across chunk boundaries
- Frontend
apiUrlpoints tohttp://localhost:3001/api/chat - Frontend uses
streamProtocol={openAIAdapter()}andopenAIMessageFormat -
componentLibrary={openuiChatLibrary}prop passed toFullScreen - CSS import in root layout (
@openuidev/react-ui/components.css)
Error Patterns
| 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 | Add http = "1" to Cargo.toml (already in the example) or import from axum::http |
static_mut_refs warning on static mut | Rust 2024 deprecates raw static mut access | Use OnceLock<String> or carry state in State<Arc<AppState>> (this example uses the latter) |
| Connection reset | Tokio runtime panic | Check .await on all async calls, verify features = ["full"] |
When not to use it
- →When the frontend is not React
- →When the backend is not Rust Axum
- →When not using OpenAI-compatible NDJSON streaming
Prerequisites
Limitations
- →Requires Node.js and React for the frontend
- →Requires Rust and Cargo for the backend
- →Relies on OpenAI API key for functionality
How it compares
This skill provides a specific, pre-configured setup for generative UI with a React frontend and Rust Axum backend using SSE, offering a direct implementation path compared to building from scratch.
Compared to similar skills
openui-forge-rust side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| openui-forge-rust (this skill) | 0 | 2mo | Review | Advanced |
| fullstack-guardian | 1 | 3mo | No flags | Advanced |
| podcast-generation | 1 | 4mo | Review | Advanced |
| waller-wallpaper-session | 0 | 2mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by OthmanAdi
View all by OthmanAdi →You might also like
fullstack-guardian
Jeffallan
Use when implementing features across frontend and backend, building APIs with UI, or creating end-to-end data flows. Invoke for feature implementation, API development, UI building, cross-stack work.
podcast-generation
microsoft
Generate AI-powered podcast-style audio narratives using Azure OpenAI's GPT Realtime Mini model via WebSocket. Use when building text-to-speech features, audio narrative generation, podcast creation from content, or integrating with Azure OpenAI Realtime API for real audio output. Covers full-stack implementation from React frontend to Python FastAPI backend with WebSocket streaming.
waller-wallpaper-session
gvastethecreator
Extend or debug the Wallpaper Session, monitor drafts, preview flows, editor flow, and profile composition across React, Tauri, and Rust. Use for monitor wallpaper features, profile bugs, preview issues, or domain-model changes.
react-server
lazarv
Build applications with @lazarv/react-server — a React Server Components runtime built on Vite. Covers use directives, file-system router, HTTP hooks, caching, live components, workers, MCP, deployment, and all core APIs.
fullstack-developer
daithang59
|
app_runner
k4ilham
A skill to run the backend (Go Fiber) and frontend (React/Vite) applications. It includes pre-run checks to clear the required ports (8080 and 5173) if they are already in use.