tokio-tungstenite
Asynchronous, Tokio-native WebSocket streams built on tungstenite
Repository Health
Technical Analysis
tokio-tungstenite wraps the synchronous tungstenite WebSocket library in a Tokio-friendly async API, exposing every connection as a WebSocketStream<S> that implements the standard futures Stream and Sink traits. That means a WebSocket connection behaves like any other async stream of messages in the Tokio ecosystem — compatible with select!, combinators from futures-util, and tokio::spawn’d tasks — without the caller ever touching a blocking read or write.
The crate covers both sides of the protocol: connect_async and client_async for establishing outbound client connections, and accept_async / accept_hdr_async for accepting inbound server connections, with optional TLS (native-tls or rustls) gated behind Cargo feature flags so plaintext-only deployments don’t pull in a TLS stack at all.
What You Get
connect_async/connect_async_with_config— one-call client connections that resolve host/port from the URL, open the TCP socket, and complete the WebSocket handshakeaccept_async/accept_hdr_async— server-side handshake acceptance, with the_hdrvariant exposing a callback to inspect or add HTTP headers during the upgradeWebSocketStream<S>implementingStream<Item = Result<Message, Error>>andSink<Message>, so messages can be read and written with ordinaryfuturescombinators- Pluggable TLS via
native-tls,rustls-tls-native-roots, orrustls-tls-webpki-rootsCargo features, unified behind aMaybeTlsStreamenum and aConnectortype for custom TLS configuration - Generic support for any
AsyncRead + AsyncWritetransport, not justTcpStream— useful for testing over in-memory duplex streams or layering on custom transports
Common Use Cases
- Real-time chat, notification, or collaborative-editing backends where a Tokio-based server needs to push and receive messages over long-lived connections
- Async clients that subscribe to a WebSocket API (exchange price feeds, streaming logs, live dashboards) and fold incoming messages into an application’s event loop
- WebSocket proxies or gateways that terminate TLS and relay frames between an upstream and downstream socket using the same
Stream/Sinkabstraction on both sides - Load and protocol-conformance testing against the Autobahn Test Suite, which the crate ships dedicated client/server examples for
Under The Hood
Architecture: The crate layers cleanly around one core abstraction: compat::AllowStd<S>, a wrapper that lets the synchronous tungstenite::WebSocket (which expects std::io::Read/Write) run on top of an async AsyncRead/AsyncWrite transport. AllowStd holds two WakerProxy instances (one for reads, one for writes) so the Stream side and Sink side of a WebSocketStream can each register their own task waker without clobbering the other’s — solving the classic problem where a single stored waker only remembers the most recent poller. handshake.rs drives the handshake as a hand-rolled Future (StartedHandshakeFuture / MidHandshake) that repeatedly calls into tungstenite’s synchronous handshake state machine until it’s Interrupted (would-block, poll again) or done. connect.rs and tls.rs layer TCP connection and optional TLS negotiation (via native-tls or rustls, unified as stream::MaybeTlsStream) on top of that. lib.rs then exposes WebSocketStream<S> implementing futures_util::Stream and Sink<Message>, translating tungstenite’s WouldBlock I/O errors into Poll::Pending.
Tech Stack: Pure Rust (96% of the codebase), edition 2018, MSRV 1.85. Core dependencies are tungstenite (the underlying sync WebSocket protocol implementation, pinned to the same 0.30.0 version), tokio (only the io-util feature by default — net is pulled in only when the connect feature is enabled), futures-util (sink + std features), and log. TLS is entirely optional and additive: native-tls/tokio-native-tls, or rustls/tokio-rustls/rustls-native-certs/webpki-roots, selected via Cargo features so a plaintext-only build carries none of that weight.
Code Quality: The public API is annotated with #![deny(missing_docs, unused_must_use, unused_mut, unused_imports, unused_import_braces)], so every exported item carries a doc comment, and the crate is disciplined about warning-free code. Integration tests are thin — tests/handshakes.rs (25 lines, one round-trip handshake test) and tests/communication.rs (106 lines) — with no dedicated unit tests for the TLS wrapping paths or WebSocketConfig edge cases; confidence there instead comes from the Autobahn Test Suite examples and tungstenite’s own test suite. No unsafe code is used in the crate’s own source.
API Design: The ergonomics lean on Rust’s trait system rather than bespoke types: connect_async(url) accepts anything implementing IntoClientRequest (a plain &str, a http::Request, etc.), and the returned WebSocketStream is immediately usable with .split(), StreamExt::next(), and SinkExt::send() from futures-util — no bespoke read/write methods to learn. Feature flags keep opt-in surface area (TLS backends, connection helpers) cleanly separated from the always-on protocol/stream plumbing, and the crate re-exports tungstenite directly so callers reach protocol-level types (Message, CloseFrame, error types) without a second dependency declaration.
Used by 23 apps in this directory
Arroyo
Data Engineering · Analytics
A distributed stream processing engine written in Rust that lets you write SQL to run stateful, real-time computations over data streams with subsecond results.
Cameleer
AI Agents
A local-first desktop workspace for managing AI agents in an enterprise-style workflow — agent directory, Kanban task tracking, workspace chat, and a full runtime/audit log of agent actions and tool approvals.
cmux
Developer Tools · AI Development
A native, Ghostty-based macOS terminal with vertical tabs, agent-aware notifications, and a scriptable browser built for running many parallel AI coding agent sessions instead of juggling tmux panes.
FastGPT
AI Agents · AI Development
Build, debug, and deploy knowledge-based AI agents with a visual workflow editor, RAG retrieval, and support for any OpenAI-compatible LLM.
Fern
Developer Tools
Fern turns a single OpenAPI, AsyncAPI, or Protobuf definition into type-safe SDKs for nine languages and a hosted API documentation site, all from one CLI and one source of truth.
headroom
AI Development · Developer Tools
Compress everything your AI agent reads — tool outputs, logs, RAG chunks, and files — before it reaches the LLM, achieving 60–95% fewer tokens with the same answers.
Hook0
Devops
Open-source Webhooks-as-a-Service: deliver events to your users with auto-retry, signed payloads, and a real-time subscriber dashboard — all without building the infrastructure yourself.
hoop
Security · Monitoring
A wire-protocol gateway that enforces data masking, command blocking, approval workflows, and full session recording for engineers and AI agents accessing production infrastructure.
Huly Platform
Project Management · Team Chat · Collaboration
Open-source all-in-one workspace that replaces Linear, Jira, Slack, and Notion for product and engineering teams.