eventsource-parser

A fast, source-agnostic streaming parser for Server-Sent Events (SSE), used to build EventSource clients and stream LLM responses.

Library
npm
v4.1.1
507 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
70 /100 Good
Development Activity 72
Maintenance 68
Community 44
Maturity 56
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
82 /100 Excellent
Architecture 88
Code Quality 92
Innovation 82
Learning Curve 65

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.
  • EventSourceParserStream transform - a TransformStream<string, EventSourceMessage> for piping a decoded fetch response body straight into parsed events.
  • Full SSE field support - id, event, retry, multi-line data, and comment (:) lines are all parsed per the WHATWG spec, including BOM stripping and mixed \n/\r/\r\n line endings.
  • maxBufferSize guard - caps how much unterminated data the parser will buffer, emitting a max-buffer-size-exceeded ParseError and refusing further feed() calls until reset().
  • Typed error callbacks - onError receives a typed ParseError (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 EventSource API isn’t available or flexible enough.
  • Polyfilling EventSource in 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 19 apps in this directory

TypeScript
45%
AGPL 3.0

BrowserOS

AI Assistants · Browser

13,763

The open-source agentic Chromium browser with native AI agents, MCP server, and visual workflow automation — your data never leaves your machine.

View details
87
Repo Health
82
Technical
68
Dependency
Built with
TypeScript 45%
Rust 23%
Python 18%
Updated 4 days ago
TypeScript
96%
MIT

deepseek-harness

AI Agents · AI Development · Developer Tools

237,945

An open-source, plugin-based agent harness from DeepSeek AI that runs coding and automation agents across web, desktop, CLI, and SDK surfaces.

View details
81
Repo Health
89
Technical
74
Dependency
Built with
TypeScript 96%
Updated 5 days ago
TypeScript
50%
Other

Dify

AI Development · Design Tools · Developer Tools

157,364

Visual LLM workflow platform with RAG pipelines, agent capabilities, and model management for building production AI applications.

View details
92
Repo Health
85
Technical
66
Dependency
Built with
TypeScript 50%
Python 47%
Updated 4 days ago
Python
70%
Apache 2.0

GPT Researcher

AI Assistants · Productivity

29,650

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.

View details
91
Repo Health
91
Technical
63
Dependency
Built with
Python 70%
TypeScript 18%
Updated 6 days ago
TypeScript
98%
Other

Kibana

Analytics · Monitoring

21,301

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.

View details
98
Repo Health
87
Technical
63
Dependency
Built with
TypeScript 98%
Updated 4 days ago
Rust
56%
Apache 2.0

Magnitude

AI Development · Developer Tools

5,285

An open source inference engine that profiles your hardware, recommends the best local models, and tunes them for the coding agent you already use.

View details
78
Repo Health
83
Technical
71
Dependency
Built with
Rust 56%
TypeScript 18%
Python 11%
Updated 4 days ago
TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

28,378

"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.

View details
90
Repo Health
73
Technical
65
Dependency
Built with
TypeScript 99%
Updated 4 days ago
Clojure
56%
Other

Metabase

Analytics

49,438

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.

View details
95
Repo Health
84
Technical
64
Dependency
Built with
Clojure 56%
TypeScript 38%
Updated 4 days ago
TypeScript
98%
Other

Novu

Developer Tools

40,084

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.

View details
93
Repo Health
80
Technical
64
Dependency
Built with
TypeScript 98%
Updated 5 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers