Workflow:Openai Openai node Streaming To Client
| Knowledge Sources | |
|---|---|
| Domains | Streaming, Server_Proxy, Web_Architecture |
| Last Updated | 2026-02-15 12:00 GMT |
Overview
End-to-end process for proxying streaming OpenAI API responses from a backend server to a browser client, enabling real-time text display without exposing API credentials.
Description
This workflow addresses a common architectural need: keeping the OpenAI API key secure on the server while delivering streaming responses to the browser in real time. The server receives a user request, initiates a streaming chat completion, and proxies the Server-Sent Events (SSE) stream to the client. The SDK provides toReadableStream() to convert its proprietary stream into a Web API ReadableStream that can be piped directly to the HTTP response. On the client side, the SDK's ChatCompletionStream.fromReadableStream() or ResponseStream.fromReadableStream() reconstructs the stream for event-driven consumption. This pattern works with Express, Next.js, and other Node.js server frameworks.
Usage
Execute this workflow when building a web application that needs to display AI-generated text progressively (token-by-token) in the browser while keeping API credentials on the server. This is the standard architecture for production chat interfaces, AI writing assistants, and any interactive AI-powered web application.
Execution Steps
Step 1: Server Endpoint Setup
Create a server-side HTTP endpoint that receives user messages. This endpoint will handle the OpenAI API interaction and stream the response back to the client. The server instantiates the OpenAI client with the API key.
Key considerations:
- The API key is stored server-side only, never sent to the browser
- Accept the user's message from the request body
- Set the response Content-Type to text/plain or text/event-stream
- Works with Express, Next.js API routes, Hono, and other frameworks
Step 2: Streaming API Call
Initiate a streaming chat completion or response on the server. Use the SDK's .stream() helper method which returns a ChatCompletionStream or ResponseStream with higher-level event handling capabilities.
Key considerations:
- Use .stream() for the higher-level streaming interface
- The stream object manages SSE parsing and content accumulation internally
- Both Chat Completions and Responses API support streaming
Step 3: Stream Proxying
Convert the SDK stream to a Web ReadableStream using .toReadableStream() and pipe it to the HTTP response. This forwards the raw SSE bytes directly to the client without buffering the entire response.
Key considerations:
- Call .toReadableStream() on the stream to get a Web ReadableStream
- Iterate with for await...of and write chunks to the response
- Call res.end() when the stream is exhausted
- The stream preserves the SSE format for client-side reconstruction
Step 4: Client-Side Consumption
On the browser side, fetch the server endpoint and reconstruct the stream using the SDK's static fromReadableStream() method. This creates a client-side stream object with the same event-driven API, enabling real-time display of content as it arrives.
Key considerations:
- Use ChatCompletionStream.fromReadableStream(response.body) on the client
- The client-side stream emits the same events (content, message, etc.)
- Import the SDK client-side for type-safe stream consumption
- The browser receives chunks progressively without waiting for the full response