THE VANILLAJS
Agent UI Library
Persona helps you create agentic front-end experiences for the web, in pure JS. Lightweight, extensible, and WebMCP-native.
$npm install @runtypelabs/persona
Floating, docked, or fullscreen UX
Pick your jump-off point and customize from there: a launcher floating in the corner, a copilot docked beside your app, or a fullscreen assistant. You move between them by changing the launcher config, not your agent or app.
A launcher in the corner that opens a floating panel. The drop-in default for support, docs, sales, or onboarding. No layout config required.
import "@runtypelabs/persona/widget.css";
import { initAgentWidget } from "@runtypelabs/persona";
initAgentWidget({
target: "#chat",
config: {
apiUrl: "https://your-api.com/chat",
// floating launcher is the default
},
});
<script>
window.siteAgentConfig = {
target: "#chat",
apiUrl: "https://your-api.com/chat",
// floating launcher is the default
};
</script>
<script src="https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/install.global.js"></script>
A copilot docked beside your app: wrap a page region and Persona reveals a side panel that resizes, pushes, or overlays your layout. Point target at the column to wrap.
initAgentWidget({
target: "#workspace",
config: {
apiUrl: "https://your-api.com/chat",
launcher: { mountMode: "docked", dock: { side: "right", width: "420px" } },
},
});
<script>
window.siteAgentConfig = {
target: "#workspace",
apiUrl: "https://your-api.com/chat",
launcher: { mountMode: "docked", dock: { side: "right", width: "420px" } },
};
</script>
<script src="https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/install.global.js"></script>
A full-height assistant that owns the page: fill a container as an app surface, with an optional artifact split. Turn the launcher off.
initAgentWidget({
target: "#app",
config: {
apiUrl: "https://your-api.com/chat",
launcher: { enabled: false, fullHeight: true },
},
});
<script>
window.siteAgentConfig = {
target: "#app",
apiUrl: "https://your-api.com/chat",
launcher: { enabled: false, fullHeight: true },
};
</script>
<script src="https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/install.global.js"></script>
Operates Your App
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.
Won't Break Your Styles
Shadow DOM rendering and prefixed CSS keep widget and host styles fully separate. Drop it into any page: nothing leaks in, nothing leaks out.
Streams From Any Backend
SSE streaming with pluggable parsers. Adapt any request or event shape with customFetch and parseSSEEvent: Runtype is the fast path, not a requirement.
Style It Like It Belongs
A three-layer token tree, palette, semantic, component, with dark mode and a live theme editor. Match your brand without forking the widget.
Choose Your Integration Path
Start from a pre-built example for your stack, or ship a hosted widget with Runtype.
Or wire your own SSE backend by hand
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.
Sign in when prompted: the CLI reveals your token and lets you copy the snippet.
<script
src="https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/install.global.js"
data-runtype-token="ct_test_..."
></script>
The widget mounts on body by default. Need a specific container? Pass --target-selector "#chat" and the CLI will include a mount div and data-config in the snippet.
Need server-side flow control? Use @runtypelabs/persona-proxy.
// 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.
Let Agents Use The Tools Already On Your Page
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.
See What Persona Can Do
Agentic, layout, voice, and business scenarios: every demo is a working page you can open and inspect.