AI Docs
Chat & Streaming
Transports
Structured Outputs
Tools
Chat UI Recipes
Interrupts
MCP
Resumable Streams
Persistence
Persistence (Advanced)
Media
Embeddings
Reranking
Evaluate
Code Mode
Sandboxes
- Overview
- Quick Start
- Providers
- Harnesses
- Harness Auth
- Workspace
- Tools
- Policy
- Lifecycle & Snapshots
- Portable Snapshots
- Keep Files After Reload
- Save a Named Version
- Branch From a Version
- Send a Frozen File
- Let the Agent Save and Fork
- Pick Which Files to Keep
- What a Snapshot Stores
- Instance Durability
- Durable Runs
- Events
Sandboxes (Advanced)
Advanced
AI/LLM: This documentation page is available in plain markdown format at/ai/latest/docs/transports/websockets.md
Transports
WebSockets
You want one connection for the whole conversation, not one request per message. Use the built-in webSocket() adapter. It opens one socket for the conversation. If a durable run drops, it reconnects automatically.
1. Connect from the client#
ts
import { useChat, webSocket } from "@tanstack/ai-react";
const connection = webSocket("/api/chat-ws");
const { messages, sendMessage } = useChat({ connection });2. Accept the socket on the server#
On Cloudflare Workers or Durable Objects, use toWebSocketResponse:
ts
import { chat, memoryStream, toWebSocketResponse } from "@tanstack/ai";
import { openaiText } from "@tanstack/ai-openai";
export default {
fetch(request: Request): Response {
return toWebSocketResponse(request, {
durability: (ctx) => memoryStream(ctx.request),
onRun: ({ messages, threadId, runId }) =>
chat({
adapter: openaiText("gpt-5.6"),
messages,
threadId,
runId,
}),
});
},
};On other hosts, such as Node, accept the socket yourself. Then pass it to toWebSocketStream. See Resumable Streams: WebSockets for this setup, the wire protocol, and the reconnect details.
To use your own wire format or a server that you do not control, write a custom adapter. See Custom Transports.
Send two messages. Both replies stream over the same socket.