TheDocumentation Index
Fetch the complete documentation index at: https://docs.outkit.dev/llms.txt
Use this file to discover all available pages before exploring further.
@outkit-dev/react package provides a drop-in React component and streaming hook for rendering Outkit-enhanced AI output. Components render inside Shadow DOM for complete style isolation from your app’s CSS.
Install
The recommended way to install is through the CLI — it detects your framework, picks a profile, installs the SDK, and writes the backend proxy in one step:outkit init writes.
To install the package manually:
Architecture
Your API key must stay on your server — never expose it in client-side code:- Your backend calls
POST /render/enhancewith the API key - Your backend proxies the SSE stream to your frontend
- Your frontend feeds the response to the SDK — one line of code
Quick Start
feedResponse handles SSE parsing, design token extraction, streaming JSON parsing, and completion — all internally. Blocks update at 60fps via requestAnimationFrame batching. It throws on non-ok HTTP responses, so wrap it in try/catch.
Your
/api/enhance/:id backend endpoint should proxy the Outkit SSE stream. See Backend Proxy below for examples.useBlockStream
The streaming hook manages block state, design tokens, and batched React state updates.
Choosing a Tier
Pick the tier that matches how your backend delivers data to the browser:| Tier | Method | When to use |
|---|---|---|
| 1 | feedResponse(res) | Your backend proxies the Outkit SSE stream as-is. Start here. |
| 2 | feedSSE(text) | You’re reading the response body yourself and want to forward raw chunks. |
| 3 | feedEvent(data) | You receive individual events via WebSocket, Socket.IO, or a custom transport. |
| 4 | feedChunk / feedMeta / feedDone | You need full manual control over every event type. |
feedResponse calls feedSSE, which calls feedEvent, which calls feedChunk/feedMeta/feedDone.
Tier 1: feedResponse(response) — Recommended
The simplest integration. Pass a fetch Response and the SDK handles everything:
- Reads the SSE stream, parses
data:lines, extracts design tokens, accumulates LLM chunks, and signals completion - Returns
{ blocks, design }— the final parsed blocks and design tokens after the stream completes - Auto-resets if a previous stream is in progress (safe for rapid re-triggers)
- Throws on non-ok HTTP responses (catch and show your own error UI)
- Abortable via
reset()— cancels the in-flight reader
Tier 2: feedSSE(rawText)
For when you’re reading the response body yourself:
data: prefix stripping, \n\n event boundaries, fragment buffering across TCP chunks).
Tier 3: feedEvent(data)
For WebSocket or custom transports delivering one event at a time:
Tier 4: feedChunk / feedMeta / feedDone
Full manual control — you parse SSE yourself and call the right method:
feedChunk(data)— Appends to an internal JSON buffer, runs the streaming parser, and updates blocks.feedMeta(tokens)— Sets design tokens. Flushes any blocks that were buffered waiting for design.feedDone()— Final parse of the accumulated buffer, flush pending blocks, mark stream complete.
reset()
Clears all state: blocks, design tokens, streaming flag, and aborts any in-flight feedResponse. Call before starting a new stream.
<AIRenderer>
Renders ContentBlock[] inside Shadow DOM with full style isolation.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
blocks | ContentBlock[] | — | Array of content blocks from the stream |
design | Record<string, string> | — | CSS custom properties from your design profile |
streaming | boolean | false | Enables streaming cursor, auto-skeletons, and entry animations |
theme | "light" | "dark" | "auto" | "auto" | Color theme. "auto" detects prefers-color-scheme |
loading | boolean | false | Show skeleton placeholder instead of content |
skeletonType | "table" | "card" | "chart" | "text" | "generic" | "generic" | Skeleton variant when loading is true |
confidenceThreshold | number | 0.7 | Minimum confidence to render a component. Below this, fallback text is shown |
className | string | — | Class applied to the wrapper <div> |
onInteraction | (event: OutkitInteractionEvent) => void | — | Callback for interactive events (table sort, checkbox toggle, etc.) |
spec | ComponentBlock | — | Render a single component instead of a blocks array |
placeholder | React.ReactNode | — | Content shown when no blocks or spec provided |
Minimal Usage
Full Usage
Theme Behavior
"auto"— Watchesprefers-color-schememedia query and updates dynamically"light"/"dark"— Forces a specific mode regardless of system preference
-dark suffix (e.g. --outkit-text-dark) are automatically swapped in when the resolved theme is dark.
Design Tokens
Design tokens are CSS custom properties injected into the Shadow DOM. They come from themeta SSE event during streaming or the design field in JSON mode.
When using feedResponse or any higher-tier method, tokens are extracted and applied automatically — you just pass design to <AIRenderer>.
Available Tokens
| Token | Description | Default |
|---|---|---|
--outkit-font | Font family | System font stack |
--outkit-text | Primary text color | #0f172a |
--outkit-text-muted | Secondary text color | #64748b |
--outkit-bg | Background | #ffffff |
--outkit-bg-subtle | Subtle background (headers, code) | #f8fafc |
--outkit-bg-hover | Hover state background | #f1f5f9 |
--outkit-border | Border color | #e2e8f0 |
--outkit-radius | Border radius | 8px |
--outkit-primary | Primary accent (links, highlights) | #3b82f6 |
--outkit-success | Success state | #16a34a |
--outkit-warning | Warning state | #d97706 |
--outkit-error | Error state | #dc2626 |
Backend Proxy
Your backend proxies the Outkit API so your API key never reaches the browser.SSE Event Types
When streaming from/render/enhance, the API sends these SSE events:
| Event | Format | Description |
|---|---|---|
| Design meta | {"type":"meta","design":{...}} | Design tokens for your profile. Always first. |
| Picker meta | {"type":"meta","picker":{...}} | Internal classification metadata. Skip this. |
| LLM chunks | Raw JSON tokens | Partial JSON structure streamed token-by-token |
| Done | [DONE] | Stream complete signal |
When using
feedResponse (Tier 1) or feedSSE (Tier 2), you don’t need to handle these events manually — the SDK parses them for you.Framework-Agnostic Core
The streaming protocol handler is available as a standalone package for non-React integrations:OutkitStream with Vue, Svelte, vanilla JS, or Node.js.
Streaming Utilities
For advanced integrations, the low-level parsing functions are also exported:parseStreamingBlocks(accumulated: string): ContentBlock[]
Takes the full accumulated raw LLM output, closes unclosed JSON structures, parses, expands wire format, and returns all currently renderable blocks.
completePartialJson(partial: string): string
Closes unclosed strings, arrays, and objects so partial JSON can be parsed. Used internally by parseStreamingBlocks.
expandWireBlock(block: Record<string, unknown>): Record<string, unknown>
Expands compact wire format ({ c, v, p }) to full format ({ type, component, version, props }). The renderer does this at render time automatically.