THE VANILLAJSAgent UI Library

www.persona-chat.dev · 2026-06-29 · by Long Nguyen ·generic
Persona is an open-source, themeable AI chat widget you can add to any website in minutes. SSE streaming, agent loops, tool use, and style isolation: zero framework dependencies.

THE VANILLAJSAgent UI Library

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` Copy

We're live on Product Hunt today — your upvote means the world Persona - Add WebMCP-native AI chat to any Frontend | Product Hunt Runs on any stack \+ any SSE backend Demos that make you \[and your browser\] happy

WebMCP Storefront

WebMCP Calendar

WebMCP Slides

Bakery Assistant

Fullscreen Layout

Docked Panel

Theme Editor

← →

Click a card to open it full size

Start in a few lines

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.

Floating Docked Fullscreen

Install via

npm Script tag

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>

Open Launcher Demo

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>

Open Docked Demo

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>

Open Fullscreen Demo

Agentic

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.

Isolation

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.

Transport

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.

Theming

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.

Quick Start

Choose Your Integration Path

Start from a pre-built example for your stack, or ship a hosted widget with Runtype.

Any SSE Backend Using 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

AI SDK + WebMCP WebMCP page tools on a Vercel AI SDK backend. Source Live demo

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

Or wire your own SSE backend by hand

01

Install Persona

Add the widget package to your app.

$ npm install @runtypelabs/persona Copy

02

Mount the widget

Import the stylesheet, initialize Persona, and point it at your SSE endpoint. Adapt any request or event shape with `customFetch` and `parseSSEEvent`.

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.

Persona is built by the team at Runtype. The Runtype CLI spins up a Persona agent and client token in seconds.

01

Run the CLI setup

Create an agent, mint a client token, and get a paste-ready installer snippet.

$ npx @runtypelabs/cli@latest persona init Copy

Sign in when prompted: the CLI reveals your token and lets you copy the snippet.

Show all flags

02

Paste the installer snippet

Use the default script installer when you want the fastest path to a live widget.

<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.

WebMCP Standard

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.

Open Storefront Demo Open Calendar Demo

Demos & Patterns

See What Persona Can Do

Agentic, layout, voice, and business scenarios: every demo is a working page you can open and inspect.

WebMCP Storefront↗ WebMCP Calendar↗ WebMCP Slides↗ Bakery Assistant↗ Fullscreen Assistant↗ Docked Panel↗ Tool Approval↗ Voice Integration↗ Artifact Sidebar↗ Dynamic Components↗ Stream Animations↗ Theme Editor↗

Browse All Examples Standalone Script Samples

www.persona-chat.dev · 2 images · 35 links

Comments (0)

No comments yet