MCPcopy Index your code
hub / github.com/MatthewWid/better-sse

github.com/MatthewWid/better-sse @v0.16.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.16.1 ↗ · + Follow
100 symbols 290 edges 77 files 10 documented · 10%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Better SSE

<a href="https://www.npmjs.com/package/better-sse">
    <img src="https://img.shields.io/npm/v/better-sse?color=blue&style=flat-square" alt="npm" />
</a>
<a href="https://jsr.io/@mwid/better-sse">
    <img src="https://jsr.io/badges/@mwid/better-sse" alt="jsr" />
</a>
<a href="https://github.com/MatthewWid/better-sse/blob/master/LICENSE">
    <img src="https://img.shields.io/npm/l/better-sse?color=green&style=flat-square" alt="MIT license" />
</a>
<img src="https://img.shields.io/npm/dt/better-sse?color=grey&style=flat-square" alt="Downloads" />
<a href="https://github.com/MatthewWid/better-sse">
    <img src="https://img.shields.io/github/stars/MatthewWid/better-sse?style=social" alt="GitHub stars" />
</a>

A dead simple, dependency-less, spec-compliant server-sent events implementation written in TypeScript.

This package aims to be the easiest to use, most compliant and most streamlined solution to server-sent events that is framework-agnostic and feature-rich.

Please consider starring the project on GitHub ⭐.

Why use Server-sent Events?

Server-sent events (SSE) is a standardised protocol that allows web-servers to push data to clients without the need for alternative mechanisms such as pinging, long-polling or WebSockets.

Using SSE can allow for significant savings in bandwidth and battery life on portable devices and will work with your existing infrastructure as it operates directly over the HTTP protocol without the need for the connection upgrade that WebSockets require.

Compared to WebSockets it has comparable performance and bandwidth usage, especially over HTTP/2, and natively includes event ID generation and automatic reconnection when clients are disconnected.

Read the Getting Started guide for more.

Highlights

  • Compatible with all popular frameworks and runtimes (Express, Hono, Fastify, Nest, Next.js, Bun, Deno, etc.)
  • Fully written in TypeScript (+ ships with types directly).
  • Thoroughly tested (+ 100% code coverage!).
  • Comprehensively documented with guides and API documentation.
  • Channels allow you to broadcast events to many clients at once.
  • Event buffers allow you to batch events for increased performance and lower bandwidth usage.
  • Configurable reconnection time, message serialization and data sanitization (with good defaults).
  • Trust or ignore the client-given last event ID.
  • Automatically send keep-alive pings to keep connections open.
  • Add or override the response status code and headers.
  • Pipe streams and iterables directly from the server to the client as a series of events.
  • Support for popular EventSource polyfills event-source-polyfill and eventsource-polyfill.

See a comparison with other SSE libraries in the documentation.

Installation

Better SSE is published as a package on npm and the JSR. You can install it with any package manager:

npm install better-sse
yarn add better-sse
pnpm add better-sse
bun add better-sse
deno install jsr:@mwid/better-sse

Better SSE ships with types built in. No need to install from DefinitelyTyped for TypeScript users!

Usage

The examples below show usage with Express and Hono, but Better SSE works with any web-server framework that uses the Node HTTP module or the Fetch API.

See the Recipes section of the documentation for use with other frameworks and libraries.


Use sessions to push events to clients:

// Server - Express
import { createSession } from "better-sse"

app.get("/sse", async (req, res) => {
    const session = await createSession(req, res)
    session.push("Hello world!", "message")
})
// Server - Hono
import { createResponse } from "better-sse"

app.get("/sse", (c) =>
    createResponse(c.req.raw, (session) => {
        session.push("Hello world!", "message")
    })
)
// Client
const eventSource = new EventSource("/sse")

eventSource.addEventListener("message", ({ data }) => {
    const contents = JSON.parse(data)
    console.log(contents) // Hello world!
})

Use channels to send events to many clients at once:

import { createSession, createChannel } from "better-sse"

const channel = createChannel()

app.get("/sse", async (req, res) => {
    const session = await createSession(req, res)

    channel.register(session)

    channel.broadcast("A user has joined.", "join-notification")
})

Use batching to send multiple events at once for improved performance and lower bandwidth usage:

await session.batch(async (buffer) => {
    await buffer.iterate(["My", "huge", "event", "list"])
})

Loop over sync and async iterables and send each value as an event:

const iterable = [1, 2, 3]

await session.iterate(iterable)

Pipe readable stream data to the client as a stream of events:

const stream = Readable.from([1, 2, 3])

await session.stream(stream)

Check the API documentation and live examples for information on getting more fine-tuned control over your data such as managing event IDs, data serialization, event filtering, dispatch controls and more!

Documentation

See the documentation website for guides, usage examples, compatibility information and an API reference.

Contributing

This library is always open to contributions whether it be code, bug reports, documentation or anything else.

Please submit suggestions, bugs and issues to the GitHub issues page.

For code or documentation changes submit a pull request on GitHub.

Local Development

Install Node (with n):

curl -L https://git.io/n-install | bash
n auto

Install dependencies (with pnpm):

npm i -g pnpm
pnpm i

Run tests (with Vitest):

pnpm t

Lint and format (with Biome):

pnpm lint
pnpm format

Bundle for distribution (with tsup):

pnpm build

Documentation

The documentation is built with Astro and Starlight. Its source is located in the docs directory.

Install dependencies:

cd docs
pnpm i

Run development server:

pnpm dev

Build for distribution:

pnpm build

License

This project is licensed under the MIT license.

Extension points exported contracts — how you extend this code

BuiltInConnectionOptions (Interface)
* Options passed from `Session` `options` argument to the built-in `Connection` implementations.
src/adapters/Connection.ts
SessionOptions (Interface)
(no doc)
src/Session.ts
EventBufferOptions (Interface)
(no doc)
src/EventBuffer.ts
ChannelOptions (Interface)
(no doc)
src/Channel.ts
IterateOptions (Interface)
(no doc)
src/utils/createPushFromIterable.ts
Response (Interface)
(no doc)
examples/getting-started/server.ts
DefaultSessionState (Interface)
(no doc)
src/Session.ts
BroadcastOptions (Interface)
(no doc)
src/Channel.ts

Core symbols most depended-on inside this repo

on
called by 95
src/utils/TypedEmitter.ts
waitForConnect
called by 63
src/utils/testUtils.ts
createEventSource
called by 58
src/utils/testUtils.ts
register
called by 18
src/Channel.ts
createSession
called by 13
src/createSession.ts
once
called by 13
src/utils/TypedEmitter.ts
createRequest
called by 10
src/utils/testUtils.ts
createResponse
called by 9
src/utils/testUtils.ts

Shape

Function 39
Method 24
Class 23
Interface 14

Languages

TypeScript100%

Modules by API surface

src/utils/TypedEmitter.ts12 symbols
src/Channel.ts11 symbols
src/utils/testUtils.ts10 symbols
examples/chat/public/index.js7 symbols
src/Session.ts6 symbols
src/EventBuffer.ts5 symbols
src/utils/SseError.ts3 symbols
src/adapters/NodeHttp2CompatConnection.ts3 symbols
src/adapters/NodeHttp1Connection.ts3 symbols
src/adapters/FetchConnection.ts3 symbols
src/adapters/Connection.ts3 symbols
src/Session.test.ts3 symbols

For agents

$ claude mcp add better-sse \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page