import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("docs/ai-sdk")
# AI SDK Integration
Use json-render with the [Vercel AI SDK](https://sdk.vercel.ai) for seamless streaming. json-render supports two modes: **Standalone** (standalone UI) and **Inline** (UI embedded in conversation). See [Generation Modes](/docs/generation-modes) for a detailed comparison.
## Installation
```bash
npm install ai @ai-sdk/react
```
## Standalone Mode
In standalone mode, the AI outputs only JSONL patches. The entire response is a UI spec with no prose. This is the default mode and is ideal for playgrounds, builders, and dashboard generators.
### API Route
```typescript
// app/api/generate/route.ts
import { streamText } from "ai";
import { catalog } from "@/lib/catalog";
export async function POST(req: Request) {
const { prompt, currentTree } = await req.json();
const systemPrompt = catalog.prompt();
// Optionally include current UI state for context
const contextPrompt = currentTree
? `\n\nCurrent UI state:\n${JSON.stringify(currentTree, null, 2)}`
: "";
const result = streamText({
model: yourModel,
system: systemPrompt + contextPrompt,
prompt,
});
return result.toTextStreamResponse();
}
```
### Client
Use `useUIStream` on the client to compile the JSONL stream into a spec:
```tsx
"use client";
import { useUIStream, Renderer } from "@json-render/react";
function GenerativeUI() {
const { spec, isStreaming, error, send } = useUIStream({
api: "/api/generate",
});
return (
{error &&
{error.message}
}
);
}
```
## Inline Mode
In inline mode, the AI responds conversationally and includes JSONL patches inline. Text-only replies are allowed when no UI is needed. This is ideal for chatbots, copilots, and educational assistants.
### API Route
Use `pipeJsonRender` to separate text from JSONL patches in the stream. Patches are emitted as data parts that the client can pick up.
```typescript
// app/api/chat/route.ts
import { streamText } from "ai";
import { pipeJsonRender } from "@json-render/core";
import {
createUIMessageStream,
createUIMessageStreamResponse,
} from "ai";
import { catalog } from "@/lib/catalog";
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: yourModel,
system: catalog.prompt({ mode: "inline" }),
messages,
});
const stream = createUIMessageStream({
execute: async ({ writer }) => {
writer.merge(pipeJsonRender(result.toUIMessageStream()));
},
});
return createUIMessageStreamResponse({ stream });
}
```
### Client
Use `useChat` from the AI SDK and `useJsonRenderMessage` from json-render to extract the spec from each message:
```tsx
"use client";
import { useChat } from "@ai-sdk/react";
import { useJsonRenderMessage, Renderer } from "@json-render/react";
function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: "/api/chat",
});
return (
);
}
```
## Prompt Engineering
The `catalog.prompt()` method creates an optimized system prompt that:
- Lists all available components and their props
- Describes available actions
- Specifies the expected output format (JSONL-only or text + JSONL depending on mode)
- Includes examples for better generation
### Custom Rules
Pass custom rules to tailor AI behavior:
```typescript
const systemPrompt = catalog.prompt({
customRules: [
"Always use Card components for grouping related content",
"Prefer horizontal layouts (Row) for metrics",
"Use consistent spacing with padding=\"md\"",
],
});
```
### Inline Mode Prompt
```typescript
const inlinePrompt = catalog.prompt({ mode: "inline" });
```
In inline mode, the prompt instructs the AI to respond conversationally first, then include JSONL patches on their own lines when UI is needed. Text-only replies are allowed.
## Which Mode?
Standalone
Inline
Output
JSONL only
Text + JSONL
Text-only replies
No
Yes
System prompt
catalog.prompt()
{"catalog.prompt({ mode: \"inline\" })"}
Stream utility
useUIStream
pipeJsonRender + useJsonRenderMessage
Use case
Playgrounds, builders
Chatbots, copilots
Learn more in the [Generation Modes](/docs/generation-modes) guide.
## Next
- Learn about [progressive streaming](/docs/streaming)
- See the [chat example](https://github.com/vercel-labs/json-render/tree/main/examples/chat) for a complete implementation