Playground
Two demos — one requires nothing, one uses your real API key.
Mock demo — no key needed
Streams pre-written RAIS responses instantly. Good for seeing the protocol in action.
Hits /api/demo — a Next.js API route in this docs site. Open DevTools → Network → filter demo to watch the raw SSE stream.
Real AI demo — your API key
Connects to a real LLM via /api/chat. Your key is passed as a request header, used for this session only, never stored or logged.
What's happening under the hood
Every message you send hits /api/demo — a standard Next.js API route that emits RAIS-compliant SSE:
POST /api/demo
Content-Type: application/json
{"messages":[{"role":"user","content":"What is RAIS?"}]}
→ HTTP 200
Content-Type: text/event-stream
Cache-Control: no-cache
id: 0
data: {"type":"text","text":"RAIS"}
id: 1
data: {"type":"text","text":" is"}
id: 2
data: {"type":"text","text":" a"}
...
id: 47
data: {"type":"done"}The useAIChat hook parses these events and accumulates text tokens into the assistant message. The UI re-renders on every token — that's what creates the streaming effect you see.
The client code
The chat above is powered by @react-ai-stream/react with a custom UI component:
import { useAIChat } from '@react-ai-stream/react'
const { messages, sendMessage, loading, stop } = useAIChat({
endpoint: '/api/demo',
})That's the entire integration. The hook handles SSE parsing, message accumulation, loading state, and abort.
The server code
The API route that streams the response:
// pages/api/demo.ts
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { messages } = req.body
res.setHeader('Content-Type', 'text/event-stream')
res.setHeader('Cache-Control', 'no-cache')
res.setHeader('X-Accel-Buffering', 'no')
res.flushHeaders()
const words = generateResponse(messages).split(' ')
for (const word of words) {
res.write(`data: ${JSON.stringify({ type: 'text', text: word + ' ' })}\n\n`)
await sleep(30)
}
res.write(`data: ${JSON.stringify({ type: 'done' })}\n\n`)
res.end()
}Any server in any language that writes this pattern is RAIS-compliant.
Use this in your own project
# Scaffold a full app in 30 seconds
npx create-ai-stream-app
# Or install manually
npm install @react-ai-stream/reactimport { useAIChat } from '@react-ai-stream/react'
export default function Chat() {
const { messages, sendMessage, loading, stop } = useAIChat({
endpoint: '/api/chat', // your RAIS-compliant endpoint
})
return (
<div>
{messages.map(m => (
<div key={m.id}><b>{m.role}:</b> {m.content}</div>
))}
<input onKeyDown={e => e.key === 'Enter' && sendMessage(e.currentTarget.value)} />
{loading && <button onClick={stop}>Stop</button>}
</div>
)
}Verify your own endpoint
Run the compliance checker against any server:
npx rais-compliance http://localhost:3000/api/chatPass all 10 checks to earn the RAIS v1 Recommended badge:
✓ All 10 tests passed
RAIS v1 Recommended ✓