Getting Started
Get HyperGen running in 5 minutes. Copy two files, set up an SSE endpoint, mount an iframe, and stream your first AI-generated UI.
HyperGen is an open protocol that lets AI agents generate interactive user interfaces by streaming HTML fragments with HTMX attributes over Server-Sent Events (SSE) into sandboxed iframes. There are no SDKs to install, no JSON schemas to learn, and no framework lock-in. Any system that can output an HTML string can use HyperGen.
Prerequisites
- Runtime: Node.js 20+, Deno 2+, or Bun 1+
- HTTP framework: Anything that supports the standard
ResponseAPI (Hono, Express, Next.js Route Handlers, Deno.serve, etc.) - Frontend: Any framework (React, Vue, Svelte) or vanilla HTML/JS
Step 1: Copy the Drop-in Files
HyperGen follows the code ownership model: you copy source files into your project and own them. There is no npm install.
Copy these files from packages/dropin/src/:
| File | Where | Purpose |
|---|---|---|
hypergen-server.ts | Your server | SSE streaming, bootstrap HTML generation |
hypergen-client.ts | Your frontend | Iframe mounting, theme injection, lifecycle |
hypergen-theme.ts | Either (optional) | TypeScript types for CSS variables |
Both files have zero external dependencies -- they use only standard Web APIs.
Step 2: Set Up the Server
You need two HTTP endpoints:
- Bootstrap endpoint -- serves the HTML document that goes inside the iframe
- SSE endpoint -- streams HTML fragments to the iframe
// server.ts
import { bootstrapHtml, createSSEStream, HyperGenResponse } from "./hypergen-server";
// Serve the iframe bootstrap document
app.get("/bootstrap", () => {
return new Response(
bootstrapHtml({ sseEndpoint: "/api/stream" }),
{ headers: { "Content-Type": "text/html" } },
);
});
// Stream HTML fragments via SSE
app.get("/api/stream", () => {
const stream = createSSEStream(async function* () {
yield "<h1>Hello from HyperGen!</h1>";
yield "<p>This HTML was streamed via SSE.</p>";
});
return HyperGenResponse(stream);
});bootstrapHtml() generates a complete HTML document with HTMX loaded from CDN, the SSE extension wired up, a postMessage bridge for host communication, and a ResizeObserver for auto-sizing.
createSSEStream() takes an async generator of HTML strings and returns a ReadableStream with proper SSE formatting and keep-alive pings.
HyperGenResponse() wraps the stream in a Response with correct SSE headers.
Step 3: Mount the Iframe in Your Frontend
// client.ts
import { mountHyperGen } from "./hypergen-client";
const controller = mountHyperGen(
document.getElementById("agent-ui")!,
{ bootstrapUrl: "/bootstrap" },
);
// Optional: inject your app's theme
controller.setTheme({
"--hg-accent": "#7c3aed",
"--hg-surface": "#ffffff",
});
// Optional: react to content size changes
controller.onResize((height) => {
console.log("Content height:", height);
});mountHyperGen() creates a sandboxed <iframe> with sandbox="allow-scripts allow-same-origin allow-forms", loads the bootstrap document, and returns a HyperGenController for managing the iframe lifecycle.
Step 4: Generate HTML from Your Agent
The server-side async generator is where your agent produces UI. Each yield sends one SSE event containing an HTML fragment that HTMX renders into the iframe.
app.get("/api/stream", () => {
const stream = createSSEStream(async function* () {
// Call your AI agent
const response = await agent.chat("Show me a dashboard");
// Stream the HTML it generates
yield response.html;
// Or build HTML from structured data
yield `
<div style="padding: 16px; background: var(--hg-surface-elevated); border-radius: var(--hg-radius);">
<h2 style="color: var(--hg-text);">Dashboard</h2>
<button
hx-post="/api/action"
hx-vals='{"action": "refresh"}'
hx-target="closest div"
hx-swap="outerHTML"
style="background: var(--hg-accent); color: var(--hg-accent-fg); border: none; padding: 8px 16px; border-radius: var(--hg-radius-sm); cursor: pointer;">
Refresh
</button>
</div>
`;
});
return HyperGenResponse(stream);
});
// Handle user interactions sent by HTMX
app.post("/api/action", async (c) => {
const body = await c.req.parseBody();
// Return new HTML that HTMX swaps in
return c.html("<div>Updated at " + new Date().toLocaleTimeString() + "</div>");
});The key insight: the agent's output IS the UI. No JSON translation, no component catalog lookup -- just HTML with HTMX attributes for interactivity and --hg-* CSS variables for theming.
Complete Minimal Example
Here is a complete working example using Hono (swap in any framework):
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { bootstrapHtml, createSSEStream, HyperGenResponse } from "./hypergen-server";
const app = new Hono();
app.get("/", (c) => c.html(`<!DOCTYPE html>
<html><head><title>HyperGen Demo</title></head>
<body>
<h1>My App</h1>
<div id="agent-ui"></div>
<script type="module">
import { mountHyperGen } from "/hypergen-client.js";
mountHyperGen(document.getElementById("agent-ui"), {
bootstrapUrl: "/bootstrap",
});
</script>
</body></html>`));
app.get("/bootstrap", (c) => c.html(
bootstrapHtml({ sseEndpoint: "/api/stream", swapStrategy: "beforeend" })
));
app.get("/api/stream", () => HyperGenResponse(
createSSEStream(async function* () {
yield '<p style="color: var(--hg-text);">Loading dashboard...</p>';
await new Promise((r) => setTimeout(r, 1000));
yield `<div style="background: var(--hg-surface-elevated); padding: 16px; border-radius: var(--hg-radius); border: 1px solid var(--hg-border);">
<h2>Welcome</h2>
<p>This UI was streamed by an AI agent.</p>
<button hx-post="/api/action" hx-swap="outerHTML"
style="background: var(--hg-accent); color: var(--hg-accent-fg); border: none; padding: 8px 16px; border-radius: var(--hg-radius-sm); cursor: pointer;">
Click me
</button>
</div>`;
})
));
app.post("/api/action", (c) => c.html(
'<div style="color: var(--hg-accent); font-weight: bold;">Button clicked!</div>'
));
serve({ fetch: app.fetch, port: 3000 });What's Next
- Server Setup Guide -- deep dive into
bootstrapHtml(),createSSEStream(), and framework-specific patterns - Client Setup Guide -- iframe mounting, React/Vue/Svelte integration, resize handling
- Theming Guide -- CSS variables, light/dark themes, dynamic switching
- Agent Integration Guide -- connect Claude, OpenAI, Ollama, or custom agents
- Specification -- formal protocol definitions