eventsource-stream
Parse a byte stream into Server-Sent Events for building Rust EventSource clients
Repository Health
Technical Analysis
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
Eventsourcetrait adding.eventsource()to anyStreamof bytes-like chunks- An SSE parser (
nom-based) handling multi-linedata:,event:,id:, andretry:fields per the SSE spec no_stdsupport (withalloc) for constrained environments, gated behind thestdfeature- UTF-8 boundary-safe chunk reassembly via an internal
utf8_streammodule, so events aren’t corrupted by chunk splits mid-character - Minimal dependency footprint:
futures-core,nom, andpin-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_stdor 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 Quality — tests/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.
Used by 3 apps in this directory
Laminar
AI Development · Monitoring
Open-source observability platform purpose-built for AI agents — trace, evaluate, debug, and monitor at scale with SQL access and real-time replay.
Meilisearch
Search
Lightning-fast hybrid search engine with AI-powered semantic and full-text retrieval for modern applications.
Vibe Kanban
AI Agents · AI Code Assistants · Project Management
A kanban board for planning work and dispatching Claude Code, Codex, Gemini CLI, and eight other coding agents into isolated git worktrees, then reviewing and merging their diffs from one UI.