Skip to content
cccskills
FreePublished on GitHub

openui-forge-go

OpenUI generative UI with Go (net/http) backend. Direct OpenAI API streaming via HTTP.

The English summary is being prepared. Showing the original description.

Works withOpenAI
See how to install

Files included (1)

  • SKILL.md6.3 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

OpenUI Forge — Go

Build generative UI apps with a React frontend + Go backend. Streams OpenAI API responses directly via net/http.

Activation Triggers

  • "openui go", "openui golang", "openui go backend"
  • "generative ui go", "go streaming ui backend"

Prerequisites

  • Node.js >= 22 (24 LTS recommended) + React >= 18.3.1 (19+ recommended) (frontend)
  • Go >= 1.24 (backend; 1.23 and older are out of security support as of Go 1.26)
  • OPENAI_API_KEY environment variable set

Quick Start

  1. Create the React frontend and install OpenUI deps:
npm install @openuidev/react-ui @openuidev/react-headless @openuidev/react-lang lucide-react zod
  1. Generate the system prompt:
npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt
  1. Create the Go backend (see Full Code below)
  2. Run: go run main.go on :8080, frontend on :3000

Full Code

Backend: backend/go.mod

module openui-backend

go 1.24

require (
    github.com/joho/godotenv v1.5.1
)

Backend: backend/main.go

package main

import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	_ "github.com/joho/godotenv/autoload"
)

var systemPrompt string

func init() {
	data, err := os.ReadFile("system-prompt.txt")
	if err != nil {
		log.Fatal("system-prompt.txt not found: ", err)
	}
	systemPrompt = string(data)
}

func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
		w.Header().Set("Vary", "Origin")
		w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
		if r.Method == "OPTIONS" {
			w.WriteHeader(204)
			return
		}
		next.ServeHTTP(w, r)
	})
}

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

type ChatRequest struct {
	Messages []Message `json:"messages"`
}

func chatHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", 405)
		return
	}

	var req ChatRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "Bad request", 400)
		return
	}

	messages := append([]Message{{Role: "system", Content: systemPrompt}}, req.Messages...)
	model := os.Getenv("OPENAI_MODEL")
	if model == "" {
		model = "gpt-5.5"
	}
	body, _ := json.Marshal(map[string]interface{}{
		"model": model, "stream": true, "messages": messages,
	})

	apiReq, _ := http.NewRequest("POST", "https://api.openai.com/v1/chat/completions", bytes.NewReader(body))
	apiReq.Header.Set("Content-Type", "application/json")
	apiReq.Header.Set("Authorization", "Bearer "+os.Getenv("OPENAI_API_KEY"))

	resp, err := http.DefaultClient.Do(apiReq)
	if err != nil {
		http.Error(w, "OpenAI request failed", 502)
		return
	}
	defer resp.Body.Close()

	w.Header().Set("Content-Type", "text/event-stream")
	w.Header().Set("Cache-Control", "no-cache")
	w.Header().Set("Connection", "keep-alive")

	flusher, ok := w.(http.Flusher)
	if !ok {
		http.Error(w, "Streaming not supported", 500)
		return
	}

	// Forward upstream SSE line-by-line so the client sees tokens as they
	// arrive instead of waiting for the whole stream to complete.
	scanner := bufio.NewScanner(resp.Body)
	scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
	for scanner.Scan() {
		line := scanner.Bytes()
		if _, err := w.Write(line); err != nil {
			return
		}
		if _, err := w.Write([]byte("\n")); err != nil {
			return
		}
		flusher.Flush()
	}
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/api/chat", chatHandler)

	fmt.Println("Go backend listening on :8080")
	log.Fatal(http.ListenAndServe(":8080", corsMiddleware(mux)))
}

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:8080/api/chat"
    />
  );
}

The Go backend forwards OpenAI's SSE stream line-by-line with a bufio.Scanner loop, flushing after each line (no io.Copy), so the client sees tokens as they arrive. Pair it with openAIAdapter() on the frontend. openAIReadableStreamAdapter() is for NDJSON (no data: prefix) and will silently produce no output here.

An official OpenAI Go SDK exists (github.com/openai/openai-go/v3, ~v3.41.0, requires Go 1.22+) as an alternative to hand-rolling the HTTP call. This skill keeps raw net/http as the dependency-free default. Note the SDK still ships small, limited breaking changes between releases (per its own README, some backwards-incompatible changes land in minor versions), so pin a version if you adopt it.

System Prompt Generation

npx @openuidev/cli generate ./src/lib/library.ts --out backend/system-prompt.txt

Validation Checklist

  • system-prompt.txt exists in the Go backend directory
  • OPENAI_API_KEY is set in environment or .env
  • CORS middleware allows the frontend origin
  • Response streams SSE directly from OpenAI API (passthrough)
  • Frontend apiUrl points to http://localhost:8080/api/chat
  • Frontend uses streamProtocol={openAIAdapter()} and openAIMessageFormat
  • componentLibrary={openuiChatLibrary} prop passed to FullScreen
  • CSS import in root layout (@openuidev/react-ui/components.css)

Error Patterns

ErrorCauseFix
CORS blockedOrigin mismatchUpdate Access-Control-Allow-Origin in middleware
system-prompt.txt not foundFile missing from backend dirRun CLI generate command
502 Bad GatewayOpenAI API unreachable or key invalidCheck OPENAI_API_KEY and network
Stream not flushingMissing http.FlusherEnsure handler calls flusher.Flush()
Empty responseBody not forwardedVerify the bufio.Scanner loop writes and flushes each line

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Build generative UI with OpenUI — any LLM provider, any backend language. Scaffold, integrate, validate.

The English summary is being prepared. Showing the original description.

OthmanAdi/openui-forge22Updated Aug 3, 2026

OpenUI generative UI with Anthropic Claude SDK backend. Stream conversion to OpenAI NDJSON format.

The English summary is being prepared. Showing the original description.

OthmanAdi/openui-forge22Updated Aug 3, 2026

OpenUI generative UI with C# ASP.NET Core Minimal API backend. Direct OpenAI API SSE streaming via HttpClient on .NET 10.

The English summary is being prepared. Showing the original description.

OthmanAdi/openui-forge22Updated Aug 3, 2026

OpenUI generative UI with Elixir Phoenix backend. Chunked SSE streaming via Plug.Conn and Req.

The English summary is being prepared. Showing the original description.

OthmanAdi/openui-forge22Updated Aug 3, 2026

OpenUI generative UI with a Java Spring Boot (WebFlux) backend. Streams the OpenAI API directly via WebClient as SSE.

The English summary is being prepared. Showing the original description.

OthmanAdi/openui-forge22Updated Aug 3, 2026

OpenUI generative UI with LangChain/LangGraph backend. Supports ChatOpenAI and ChatAnthropic.

The English summary is being prepared. Showing the original description.

OthmanAdi/openui-forge22Updated Aug 3, 2026

See all skills by OthmanAdi

Report a problem with this skill