eventsource-stream

Parse a byte stream into Server-Sent Events for building Rust EventSource clients

Library
Cargo
v0.2.3
39stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
22/100Needs Attention
Development Activity0
Maintenance0
Community16
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture70
Code Quality68
Innovation62
Learning Curve75

eventsource-stream is a small Rust crate that turns any Stream of byte chunks into a Stream of parsed Server-Sent Events (SSE), following the same wire format used by browser EventSource implementations. It’s a building block rather than a full client: it does the SSE framing and parsing work (splitting on event boundaries, extracting event/data/id/retry fields) so higher-level HTTP clients only need to supply the raw byte stream.

The crate is no_std-compatible (with an alloc fallback) and works with any bytes-producing stream, most commonly reqwest’s bytes_stream(), via an Eventsource extension trait that adds an .eventsource() adapter method.

What You Get

  • Eventsource trait adding .eventsource() to any Stream of bytes-like chunks
  • An SSE parser (nom-based) handling multi-line data:, event:, id:, and retry: fields per the SSE spec
  • no_std support (with alloc) for constrained environments, gated behind the std feature
  • UTF-8 boundary-safe chunk reassembly via an internal utf8_stream module, so events aren’t corrupted by chunk splits mid-character
  • Minimal dependency footprint: futures-core, nom, and pin-project-lite

Common Use Cases

  • Consuming Server-Sent Event endpoints (e.g. LLM streaming APIs, live notification feeds) from a Rust HTTP client like reqwest
  • Building a higher-level SSE/EventSource client crate on top of this parsing primitive
  • Streaming real-time updates from a web service into a Rust backend or CLI tool without a full WebSocket dependency
  • Embedding SSE parsing in no_std or constrained targets that still have an allocator

Under The Hood

Architecture — The crate is organized around a small pipeline: utf8_stream.rs reassembles raw byte chunks into valid UTF-8 boundaries (handling multi-byte characters split across network reads), parser.rs uses the nom parser-combinator library to tokenize SSE fields (event:, data:, id:, retry:, comments), and event_stream.rs (the largest module at 563 lines) drives a Stream-implementing EventStream<S> state machine that pulls from the UTF-8 stream, feeds the parser, and yields Event values or EventStreamError. traits.rs defines the public Eventsource extension trait that adapts any Stream<Item = Result<impl AsRef<[u8]>, E>> via .eventsource().

Tech Stack — Rust 2018 edition, no_std-compatible via alloc behind a std feature flag; depends on futures-core (stream trait, no executor), nom 7.1 for parsing, and pin-project-lite for safe pin projection in the stream state machine. Dev-dependencies (reqwest, tokio, http, url) are used only for the documented example and integration test.

Code Qualitytests/eventsource-stream.rs is an integration test exercising the stream against constructed SSE payloads, and examples/request.rs plus examples/server.php provide an end-to-end runnable demo (a tiny PHP SSE server paired with the Rust client). The crate is compact (~900 lines across 6 modules) with each module handling one concern (UTF-8 safety, parsing, stream driving, public API), though it has had only 2 contributors and no commits since mid-2024.

API Design — The API is a single extension trait plus one adapter method (.eventsource()), so adoption is a one-line addition to an existing byte stream — about as low-boilerplate as a streaming parser can get. The tradeoff is that it’s intentionally low-level: callers get parsed Event values but must build their own reconnection/retry logic on top, since this crate only handles framing, not the full EventSource reconnection protocol.

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

Search