reqwest-eventsource

A Rust Server-Sent Events (SSE) client that wraps reqwest with automatic reconnection and retries

Library
Cargo
v0.6.0
72stars
MIT OR Apache-2.0

Repository Health

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

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture82
Code Quality78
Innovation80
Learning Curve75

reqwest-eventsource is a small Rust library that layers a Server-Sent Events (SSE) client on top of the popular reqwest HTTP client. It exposes an EventSource type that implements futures::Stream, yielding Open and Message events as data arrives from an SSE endpoint, so you can consume server push streams with idiomatic async Rust.

Beyond the raw stream, the crate handles the operational details of long-lived SSE connections: it validates the response status and text/event-stream content type, tracks the Last-Event-ID header across reconnects, and transparently retries failed requests using a pluggable retry policy (exponential backoff by default). It works on both native and wasm32 targets and integrates with any reqwest RequestBuilder via an extension trait.

What You Get

  • An EventSource type implementing futures::Stream that yields Event::Open and Event::Message items
  • Automatic reconnection with Last-Event-ID tracking and a pluggable RetryPolicy (exponential backoff, constant, or never)
  • A RequestBuilderExt extension trait to build an EventSource directly from any reqwest RequestBuilder
  • Response validation for status codes and the text/event-stream content type, surfaced as typed errors
  • Support for both native and wasm32 targets

Common Use Cases

  • Consuming SSE streams from LLM/chat completion APIs that stream tokens as events
  • Subscribing to real-time server push feeds such as notifications, live metrics, or activity logs
  • Building resilient long-lived connections that need to reconnect and resume after transient failures
  • Adding SSE support to an existing reqwest-based HTTP client without switching libraries

Under The Hood

Architecture - The core is EventSource in src/event_source.rs, a pin_project! state machine that implements futures::Stream. It holds an in-flight response future (next_response), an active byte-stream-turned-event-stream (cur_stream), and an optional reconnect delay. poll_next advances these in order: it waits out any retry delay, resolves the pending request, validates it via check_response (status must be 200 and content type text/event-stream), emits Event::Open, then pumps parsed MessageEvents from eventsource_stream. Errors route through handle_error, which consults the RetryPolicy to schedule a backoff delay or close the stream. RequestBuilderExt in src/reqwest_ext.rs adds an eventsource() method to reqwest’s RequestBuilder.

Tech Stack - Pure Rust (edition 2018). It builds on reqwest 0.12 (stream feature) and eventsource-stream 0.2 for SSE parsing, with futures-core for stream/future traits, pin-project-lite for safe pin projection, futures-timer for reconnect delays, nom for parse-error typing, mime for content-type checks, and thiserror for the error enum. Conditional cfg(target_arch = "wasm32") type aliases swap Box/Local future and stream types for wasm compatibility.

Code Quality - The code is compact (~16KB across five focused modules) with thorough doc comments on all public items. Errors are modeled as a single thiserror-derived Error enum with transparent variants, and retry policies are cleanly abstracted behind a RetryPolicy trait with three provided implementations. The repository ships runnable examples/ (a simple client and a rocket server) but contains no unit or integration tests, relying instead on the well-tested underlying eventsource-stream crate.

API Design - The public surface is small and ergonomic: EventSource::get(url) for the common case, EventSource::new(builder) or builder.eventsource() for custom requests, and standard StreamExt iteration to consume events. Naming mirrors the browser EventSource API (ReadyState, Event::Open, Event::Message, last_event_id), lowering the learning curve for developers familiar with SSE, and retry behavior is customizable without touching the consumption loop.

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