EventSource
WhatWG/W3C-compliant EventSource (Server-Sent Events) client for JS runtimes
Repository Health
Technical Analysis
eventsource is a minimal, spec-compliant implementation of the WhatWG/W3C EventSource API for environments that don’t ship one natively — Node.js, Bun, Deno, and older browsers. It parses text/event-stream responses into typed message/custom events with automatic reconnection, matching the exact behavior defined by the living standard rather than adding an opinionated API on top.
Because it builds on fetch and ReadableStream instead of raw sockets, it accepts a pluggable fetch implementation — letting consumers add custom headers, proxy support, or HTTP/2 via libraries like undici without forking the client.
What You Get
- A
EventSourceclass implementing the full WhatWG event-stream parsing and reconnection spec - Custom event listening via
addEventListener('eventType', handler)for named SSE event types - A pluggable
fetchoption for adding auth headers, proxies (viaundici), or HTTP/2 support - Extended
errorevents exposingmessageand HTTPcodefor diagnosing failed connections - Support across Node.js 20+, Bun, Deno, and all evergreen browsers
Common Use Cases
- Consuming a server-sent-events API from a Node.js backend or CLI tool
- Streaming LLM/chat completions token-by-token from a server that emits SSE
- Adding authentication headers or a corporate proxy to an SSE connection via a custom
fetch - Polyfilling
EventSourcein test environments or older browsers that lack native support
Under The Hood
Architecture: The library is a thin, spec-faithful wrapper: src/EventSource.ts (605 lines) extends the native EventTarget, delegates stream parsing to the separate eventsource-parser package via createParser, and drives reconnection/backoff itself, while src/errors.ts and src/types.ts define the typed error and fetch-abstraction surface — there’s no framework or DI, just one class implementing a W3C state machine.
Tech Stack: TypeScript compiled to dual ESM/CJS output via pkg-utils, with zero runtime dependencies beyond eventsource-parser. It deliberately depends on fetch, ReadableStream, and TextDecoder rather than Node’s http module, which is what lets the same code run unmodified on Node 20+, Bun, Deno, and browsers.
Code Quality: Test suites are split per-runtime (test/node, test/browser, test/bun, test/deno), each run through tsx or the runtime’s own test runner, and posttest chains ESLint plus a strict tsc --noEmit — a deliberate choice to catch cross-runtime type drift rather than relying on a single Node-only test pass.
API Design: The public API is intentionally a strict subset of the browser standard (CONNECTING/OPEN/CLOSED constants, addEventListener, .close()) with one pragmatic extension — a fetch constructor option — that avoids inventing new concepts, so migrating code that used to run only in the browser is close to a drop-in exercise, backed by an explicit MIGRATION.md for v2→v3 users.