By Sagar Shankaran, Founder of CallSphere
Use tRPC v11 async generators to stream OpenAI tokens over SSE through a fully type-safe stack. Real Next.js App Router code, no WebSockets needed.
Key takeaways
TL;DR — tRPC v11 added
async function*procedures that stream over Server-Sent Events. Wrap an OpenAIstream: truecall and you get end-to-end type-safe token streaming with zero WebSocket plumbing.
A Next.js 15 App Router chat UI with a tRPC chat.stream mutation that yields OpenAI tokens one at a time. The client uses the new useSubscription hook so React renders deltas as they arrive — no manual fetch + reader code.
@trpc/server@^11, @trpc/client@^11, @trpc/react-query@^11, zod@^3.23.openai@^4.70 and an API key.flowchart LR
UI[React useSubscription] -- SSE --> RT[tRPC HTTP route]
RT -- async generator --> OA[OpenAI stream: true]
OA -- delta --> RT --> UI
```ts import { z } from "zod"; import OpenAI from "openai"; import { router, publicProcedure } from "./trpc";
const oa = new OpenAI();
export const chatRouter = router({ stream: publicProcedure .input(z.object({ messages: z.array(z.object({ role: z.enum(["user","assistant","system"]), content: z.string(), })) })) .subscription(async function* ({ input, signal }) { const s = await oa.chat.completions.create({ model: "gpt-4o-mini", messages: input.messages, stream: true, }, { signal }); for await (const chunk of s) { const delta = chunk.choices[0]?.delta?.content; if (delta) yield { type: "delta", text: delta }; } yield { type: "done" }; }), }); ```
```ts // app/api/trpc/[trpc]/route.ts import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import { appRouter } from "@/server/router";
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
const handler = (req: Request) => fetchRequestHandler({ endpoint: "/api/trpc", req, router: appRouter, createContext: () => ({}) });
export { handler as GET, handler as POST }; ```
```ts import { createTRPCReact, httpSubscriptionLink, splitLink, httpBatchLink } from "@trpc/react-query";
export const trpc = createTRPCReact
```tsx "use client"; import { useState } from "react"; import { trpc } from "@/lib/trpc";
export function Chat() { const [text, setText] = useState(""); const [reply, setReply] = useState(""); const [run, setRun] = useState<any[]>([]);
trpc.chat.stream.useSubscription( { messages: run }, { enabled: run.length > 0, onData: (e) => e.type === "delta" && setReply((r) => r + e.text) }, );
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
return ( <form onSubmit={(e) => { e.preventDefault(); setReply(""); setRun([{ role: "user", content: text }]); }}> <input value={text} onChange={(e) => setText(e.target.value)} />
{reply}
);
}
```
When the user navigates away, React Query unmounts the subscription. tRPC v11 propagates the abort signal into the OpenAI client ({ signal }), which cancels the upstream request — saving tokens.
runtime = "edge" works for SSE but limits some Node-only OpenAI helpers — pick runtime = "nodejs" if you need stream.controller.X-Accel-Buffering: no or use responseInit: { headers: { "X-Accel-Buffering": "no" } }.httpLink and parse JSON-lines.CallSphere's Sales product (Node.js 20 + React 18 + Vite) ships a near-identical tRPC pipe for real-time SDR chat across 37 agents, 90+ tools, and 115+ DB tables — used in 6 verticals at $149/$499/$1,499 pricing with a 14-day no-card trial and 22% affiliate. p95 first-token latency is ~280ms.
Does this work with React Server Components? The streaming part is a client component, but the trigger can be a server action that primes run.
Why not WebSockets? SSE is HTTP/1.1 friendly, survives serverless, and tRPC v11 picked it as the default for that reason.
Can I stream tool calls? Yes — yield { type: "tool_call", name, args } from the generator and render a tool UI on the client.
What about Vercel AI SDK? AI SDK and tRPC are complementary — wrap streamText inside a tRPC subscription if you want both.
Written by
Sagar Shankaran· Founder, CallSphere
Sagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
AI SDK 5 ships fully typed chat for React, Svelte, Vue, and Angular plus first-class agent loop primitives. Here are the patterns that matter for shipping in 2026.
Mastra.ai is becoming the go-to TypeScript agent framework in 2026. Workflows, RAG, evals, and an honest comparison with Vercel AI SDK 5 for serious teams.
LangChain v1 + LangGraph v1 in JS, paired with Ollama, gives you a fully local chat agent with tools, memory, and structured output. No OpenAI key required.
Convex's reactive queries auto-push every transcript update to every subscribed client. Real working code for actions, mutations, and OpenAI Realtime streaming.
The MCP TypeScript SDK 1.0 makes server development straightforward and type-safe. A walkthrough from scaffold to a deployed Cloud Run service ready for production traffic.
AI SDK 5 ships agent loops, MCP client, and Generative UI v2 — the cleanest TypeScript stack for shipping AI features in 2026 without rewriting your frontend.
© 2026 CallSphere LLC. All rights reserved.
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.