eventsource-parser
A fast, source-agnostic streaming parser for Server-Sent Events (SSE), used to build EventSource clients and stream LLM responses.
Repository Health
Technical Analysis
eventsource-parser is a low-level, streaming parser for the Server-Sent Events (SSE) protocol used by the browser EventSource API. It makes no assumptions about how you retrieve the underlying byte stream — you create a parser instance and feed it chunks of text, complete or partial, and it calls back with fully parsed messages (id, event, and data fields), reconnection retry intervals, and stream comments as they arrive. A TransformStream variant (eventsource-parser/stream) is also exported for environments that support the Streams API, letting you pipe a fetch response body directly into a stream of parsed EventSourceMessage objects.
Because it doesn’t own the transport, eventsource-parser is the building block underneath higher-level clients — its author’s own eventsource-client package, EventSource polyfills, and countless bespoke integrations for streaming LLM chat completions over SSE. Internally the parser is tuned for exactly that workload: trailing fragments are buffered and joined once rather than concatenated on every feed() call (avoiding O(N²) blowups on payloads split across many small chunks), the common single-line event shape is dispatched without ever touching the internal data buffer, and an optional maxBufferSize guards against unbounded memory growth from a server that never terminates a line.
What You Get
- Chunk-based
feed()API - pass partial or complete SSE payloads in any order and the parser accumulates state across calls until a full message is dispatched. EventSourceParserStreamtransform - aTransformStream<string, EventSourceMessage>for piping a decodedfetchresponse body straight into parsed events.- Full SSE field support -
id,event,retry, multi-linedata, and comment (:) lines are all parsed per the WHATWG spec, including BOM stripping and mixed\n/\r/\r\nline endings. maxBufferSizeguard - caps how much unterminated data the parser will buffer, emitting amax-buffer-size-exceededParseErrorand refusing furtherfeed()calls untilreset().- Typed error callbacks -
onErrorreceives a typedParseError(invalid-retry,unknown-field,max-buffer-size-exceeded) instead of throwing, so malformed streams degrade gracefully.
Common Use Cases
- Streaming LLM chat responses - parsing token-by-token SSE output from OpenAI-, Anthropic-, or self-hosted-compatible chat completion endpoints.
- Building a custom EventSource client - implementing reconnect logic, custom headers, or non-browser runtimes (Node.js, Deno, Bun, edge/serverless) where the native
EventSourceAPI isn’t available or flexible enough. - Polyfilling
EventSourcein environments without it - pairing the parser with a fetch-based transport to reproduce the browser API’s behavior server-side. - Proxying or relaying SSE streams - re-parsing and re-emitting events when building a gateway or middleware that inspects or transforms a Server-Sent Events stream in transit.
Under The Hood
Architecture
The library is split cleanly by responsibility: parse.ts implements the core state machine (createParser) that consumes string chunks and dispatches parsed fields through closures over mutable parser state (pendingFragments, data, id, eventType), stream.ts wraps that core in a TransformStream subclass (EventSourceParserStream) for Streams-API environments, types.ts defines the public ParserConfig/ParserCallbacks/EventSourceMessage contracts, and errors.ts defines a small typed ParseError class. There is no shared mutable module state — each createParser() call closes over its own buffers — and the fast path (processLines) is deliberately duplicated from the slow, spec-correct CR/LF-aware path to avoid per-chunk branching overhead; changing the core buffering strategy (fragment array vs. string concatenation) is the one change that would ripple through the whole hot path.
Tech Stack
Written in strict TypeScript (ES2018 target, ESM-only, verbatimModuleSyntax, noUncheckedIndexedAccess) with zero runtime dependencies. Builds go through tsc --build for declaration output plus a separate bundle-size check via esbuild/terser; oxlint and oxfmt (the Rust-based Oxc toolchain) handle linting and formatting instead of ESLint/Prettier; knip checks for unused exports; releases are managed with Changesets; and tests run under vitest across Node, Bun, and Deno via dedicated test:node/test:bun/test:deno scripts.
Code Quality
The test suite (parse.test.ts, stream.test.ts, plus dedicated multibyte and benchmark-fixture suites) totals roughly four times the line count of the library source itself, covering SSE edge cases like split multi-byte characters, BOM variants, mixed line terminators, and buffer-limit termination. The tsconfig.json enables an unusually strict rule set (noUnusedLocals, noPropertyAccessFromIndexSignature, noFallthroughCasesInSwitch, strict), and CI workflows (test.yml, release.yml) gate merges on lint plus the full cross-runtime test matrix. Comments throughout parse.ts explain non-obvious micro-optimizations (e.g. why buffering avoids an O(N²) trap) rather than restating what the code does.
API Design
The public surface is intentionally narrow: one factory function (createParser) taking a callbacks object, plus one TransformStream subclass for the Streams-API path — there’s no class to instantiate or state to manage beyond calling feed() and, on reconnect, reset(). Getting started requires no boilerplate beyond supplying an onEvent callback, and the same callback shapes (onId, onRetry, onComment, onError) are reused identically between the callback-based and stream-based APIs, so switching between them doesn’t require relearning the message shape.
Used by 17 apps in this directory
BrowserOS
Browser · AI Assistants
The open-source agentic Chromium browser with native AI agents, MCP server, and visual workflow automation — your data never leaves your machine.
Dify
No Code Platforms · AI Development · Developer Tools
Visual LLM workflow platform with RAG pipelines, agent capabilities, and model management for building production AI applications.
GPT Researcher
Productivity · AI Assistants
The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.
Kibana
Analytics · Monitoring
Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.
Mastra Code
AI Code Assistants
"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.
Metabase
Analytics
The open-source BI platform that lets anyone ask questions and build dashboards without writing SQL — with an embedded analytics SDK and AI-powered query assistant included.
Novu
Developer Tools
Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.
Open WebUI
AI Assistants · AI Agents
The extensible, privacy-first AI platform that runs Ollama, OpenAI, and any LLM backend behind a polished, feature-packed web interface.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.