Persona helps you create agentic front-end experiences for the web, in pure JS. Lightweight, extensible, and WebMCP-native.
$npm install @runtypelabs/persona
Agentic
Expose page actions, search, carts, bookings, forms, as WebMCP tools and the agent drives them directly, with user approval built in. No backend integration required.
Isolation
Shadow DOM rendering and prefixed CSS keep widget and host styles fully separate. Drop it into any page: nothing leaks in, nothing leaks out.
Transport
SSE streaming with pluggable parsers. Adapt any request or event shape with customFetch and parseSSEEvent: Runtype is the fast path, not a requirement.
Theming
A three-layer token tree, palette, semantic, component, with dark mode and a live theme editor. Match your brand without forking the widget.
Quick Start
Start from a pre-built example for your stack, or ship a hosted widget with Runtype.
Start from a pre-built example. Each one mounts the real widget against a working backend you can clone, read, and adapt.
Bare script tag
No framework: a script-tag install over a node:http backend.
Source
OpenAI Agents
OpenAI Agents SDK (@openai/agents) backend.
Source
LangGraph.js A LangGraph.js graph streamed to the widget. Source
AI SDK + Responses Minimal AI SDK and OpenAI Responses adapters. Source
eve Vercel eve agent backend (beta). Source
Hono
One app.fetch handler on Node, Bun, Deno, Workers.
Source
Express
The callback-style (req, res) bridge.
Source
SvelteKit
A one-line Web-standard +server.ts route.
Source
Runtype proxy Runtype API proxy on Hono (Node, Vercel, Workers). Source
import "@runtypelabs/persona/widget.css";
import { initAgentWidget } from "@runtypelabs/persona";
initAgentWidget({
target: "#chat",
config: { apiUrl: "https://your-api.com/chat" },
});
Built an adapter for your stack? Contribute it back.
// Your page registers a tool…
document.modelContext.registerTool({
name: "search_products",
description: "Search the catalog.",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: ["query"],
},
async execute({ query }) {
return searchCatalog(query);
},
});
// Persona discovers it through WebMCP
// and asks before calling it.
WebMCP Standard
WebMCP gives the browser a standard place for page tools: document.modelContext. Persona discovers those tools, asks the user before calling them, and streams the result back into the conversation. Search, carts, bookings, and forms stay in your page code. The chat UI just becomes another way to use them.
Demos & Patterns
Agentic, layout, voice, and business scenarios: every demo is a working page you can open and inspect.