---
title: "Streaming and SSE"
description: "Streaming allows your server to send data to clients piece-by-piece (in chunks) rather than waiting to generate the entire response all at once. This is especially useful for large payloads, real-t..."
last_updated: "2026-10-12T08:15:16.248386+00:00"
canonical_url: "https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/guide/how-to-guides/streaming-and-sse"
---

## Overview

### Introduction to Streaming

Streaming allows your server to send data to clients piece-by-piece (in chunks) rather than waiting to generate the entire response all at once. This is especially useful for large payloads, real-time logs, AI text generation, or any scenario where you want to reduce Time to First Byte (TTFB) and show progress immediately.

Hono provides built-in streaming helpers that leverage web-standard `ReadableStream` and `WritableStream` objects, making them compatible with modern server runtimes like Node.js, Bun, Deno, and Cloudflare Workers.

### Streaming Text and Custom Content

The `stream` helper gives you low-level control over a chunked text response. You can write strings or binary data to the stream progressively and close it when you are finished.

```typescript
import { Hono } from 'hono'
import { stream } from 'hono/streaming'

const app = new Hono()

app.get('/stream', (c) => {
  return stream(c, async (stream) => {
    await stream.write('Hello ')
    await stream.sleep(1000)
    await stream.write('World!')
    await stream.writeln(' This is a new line.')
  })
})
```

If you specifically want to stream plain text with the correct `text/plain` headers and safety settings, use `streamText`:

```typescript
import { Hono } from 'hono'
import { streamText } from 'hono/streaming'

const app = new Hono()

app.get('/text', (c) => {
  return streamText(c, async (stream) => {
    await stream.write('Chunk 1\n')
    await stream.sleep(500)
    await stream.write('Chunk 2\n')
  })
})
```

### Server-Sent Events (SSE)

Server-Sent Events allow a server to push real-time updates to a client over an HTTP connection using event streams (`text/event-stream`). 

Hono provides `streamSSE` and the `SSEStreamingApi` class to simplify sending structured messages that include event names, unique IDs, retry intervals, and data payloads.

```typescript
import { Hono } from 'hono'
import { streamSSE } from 'hono/streaming'

const app = new Hono()

app.get('/sse', (c) => {
  let id = 0
  return streamSSE(c, async (stream) => {
    while (true) {
      await stream.writeSSE({
        data: `Server time is ${new Date().toISOString()}`,
        event: 'time-update',
        id: String(id++),
        retry: 3000,
      })
      await stream.sleep(1000)
    }
  })
})
```

> [!NOTE]
> `streamSSE` automatically sets the required headers (`Content-Type: text/event-stream`, `Cache-Control: no-cache`, `Connection: keep-alive`, and `Transfer-Encoding: chunked`).

### Key Concepts

* **Chunked Transfer Encoding**: An HTTP mechanism where data is sent in a series of chunks, allowing the browser to render content before the server finishes generating the whole response.
* **ReadableStream / WritableStream**: Standard web APIs used underneath Hono's streaming helpers to pipe data from the server handler to the client connection.
* **Server-Sent Events (SSE)**: A lightweight protocol for pushing text-based messages from server to client over a single long-lived HTTP connection.

### Streaming API Reference

The streaming helpers pass a stream instance into your callback function. Here are the available methods on the stream objects:

| Method / Property | Description |
| :--- | :--- |
| `stream.write(input)` | Writes a string or `Uint8Array` chunk to the stream. |
| `stream.writeln(input)` | Writes a string chunk followed by a newline character. |
| `stream.sleep(ms)` | Pauses execution for the specified number of milliseconds. |
| `stream.close()` | Closes the stream normally. |
| `stream.abort()` | Aborts the stream and cancels active readers. |
| `stream.onAbort(listener)` | Registers a callback function to run if the client disconnects or aborts. |
| `stream.writeSSE(message)` | *(SSE only)* Formats and sends an SSE message object. |
| `stream.closed` | Boolean property indicating if the stream is closed. |
| `stream.aborted` | Boolean property indicating if the stream was aborted. |

> [!WARNING]
> When using `streamSSE`, message properties (`event`, `id`, and `retry`) must not contain carriage return (`\r`) or newline (`\n`) characters, or Hono will throw an error.

## Related

- Context API Methods
- [Handling WebSockets](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/guide/how-to-guides/handling-websockets)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/llms.txt) for all pages in this wiki.
