@gistui/svelte is for Svelte 5 and SvelteKit. The package ships its Svelte source, compiled by your app’s build.
npm i @gistui/svelte @gistui/styles @gistui/catalogyarn add @gistui/svelte @gistui/styles @gistui/catalogpnpm add @gistui/svelte @gistui/styles @gistui/catalogbun add @gistui/svelte @gistui/styles @gistui/catalogRender an answer
<script lang="ts">
import "@gistui/styles/styles.css";
import { GistUI } from "@gistui/svelte";
let { answer, loading } = $props();
</script>
<GistUI source={answer} streaming={loading} onaction={(a) => console.log(a)} />Pass stream={response.body} instead to let the component read a ReadableStream. Without a component, the use:gistui action renders into any element.
With SvelteKit
import { prompt } from "@gistui/catalog";
import { textDeltas, toReadable } from "@gistui/server";
import { OPENAI_API_KEY } from "$env/static/private";
export async function POST({ request }) {
const { messages } = await request.json();
const res = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: { Authorization: `Bearer ${OPENAI_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ model: "gpt-5", stream: true, messages: [{ role: "system", content: prompt().text }, ...messages] }),
});
if (!res.ok) return new Response(await res.text(), { status: res.status });
return new Response(toReadable(textDeltas(res, "openai")));
}Props and callbacks
Props: source + streaming or stream, inline, theme, color, tokens, darkTokens, classNames, tools, mutations, allowedHosts, paused, initialState, lockUntil, openLinks, autofix (default true), components, library.
Callbacks are lower-case, as Svelte 5 events are: onaction, onerror, onstatechange, onprose, onautofix, ontoolcall.
They mean the same as in every renderer: see Renderer options.
Tools and safety
A program is untrusted: a model wrote it, possibly steered by content it read. It cannot run code.
| Option | What it does |
|---|---|
tools |
Read-only functions (or an MCP-style client, { callTool }). @query may call them as soon as the UI renders, so nothing here may change anything. |
mutations |
Functions that change something. They run only when a person presses a button. |
ontoolcall |
Called before every tool call with { name, args, kind, nodeId }. Return false to block it. |
allowedHosts |
Hosts that images, video and backgrounds may load from, for example ["cdn.example.com", "*.example.com"]. Set it when the model sees private data. |
paused |
Stops timed data refreshes. |
More in Security and Tools and live data.
Your own components
Any Svelte component (shadcn-svelte, Bits UI, your design system) can replace a built-in one.
<script lang="ts">
import { GistChildren, type GistUIComponentProps } from "@gistui/svelte";
let { props }: GistUIComponentProps = $props(); // what the model wrote
</script>
<section class="my-card"><GistChildren /></section><GistUI source={answer} components={{ Card: MyCard }} />Your components see the Svelte context around <GistUI>. For a form field, gistField(() => p.ctx) joins the GistUI Form around it (field.current.name, error, locked, value, setValue).