HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
algesten
str0m
Rust2023–2026
algesten / str0m

str0m

A Sans I/O WebRTC implementation in Rust.

8Distinct people
15Mentions
0Explicit recommenders
654GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A Sans I/O WebRTC implementation in Rust.

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year15 dated mentions

Observed mentions: 2023-05-31 11:37:42 UTC to 2026-03-19 14:15:56 UTC.

0369122023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20232024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 11 mentions; 0 submissions, 11 comments20242025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC11011
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC202
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

What Hacker News says

15 sources
Host your own broadcast, with a minimal stack: - A domain name - A VPS with a public IP (reference: indep.stream runs on a $4/month 512MB DigitalOcean droplet with 2G memory swap) - UDP port 50000 open on the VPS firewall - Nginx or Caddy + TLS certificate (Let's Encrypt / Certbot — free) - A Chromium-based browser to watch or broadcast (Chrome, Edge, Brave — Firefox not supported yet) - Rust 1.83+ and Go 1.21+ installed on the server. (Built on: str0m (Rust WebRTC engine) github.com/algesten/str0m , tokio + axum (Rust async HTTP), tokio.rs, gorilla/websocket (Go WebSocket) github.com/gorilla/websocket Choose to be sovereign if you want to, host your stream and it will be under your name or corp. Sponsored by xlovecam. If you are here for ad hominem about the sponsor, your comment is not welcome.
In No Twitch, No Middlemen. Host Your Own Livestream
I am so happy that WebRTC has so many implementations. Every developer thinks differently, it's good to have a implementation that matches your mindset. * https://github.com/shinyoshiaki/werift-webrtc (Typescript) * https://github.com/pion/webrtc (Golang) * https://github.com/webrtc-rs/webrtc (Rust) * https://github.com/algesten/str0m (Rust) * hhttps://github.com/sepfy/libpeer (C/Embedded) * https://webrtc.googlesource.com/src/ (C++) * https://github.com/sipsorcery-org/sipsorcery (C#) * https://github.com/paullouisageneau/libdatachannel (C++) * https://github.com/elixir-webrtc (Elixir) * https://github.com/aiortc/aiortc (Python) * GStreamer’s webrtcbin (C) See https://github.com/sipsorcery/webrtc-echoes for examples of some running against each other.
In WebRTC for the Curious
Yes, the established standard here is known collectively as Interactive Connectivity Establishment (ICE) [1] which WebRTC relies on -- there are a few good libraries out there that implement it and/or various elements of it [2] [3]. libp2p [4] may be what you're after if you want something geared more towards general purpose connectivity. [1] https://datatracker.ietf.org/doc/html/rfc8445 [2] https://github.com/pion/webrtc [3] https://github.com/algesten/str0m [4] https://libp2p.io
In How NAT Traversal Works (2020)
> To "time-out" in sans-IO style means that your state machine has an `Instant` internally and, once called at a specific point in the future, compares the provided `now` parameter with the internal timeout and changes its state accordingly. See [0] for an example. This part of the post was clear -- I didn't ask any clarifications about that, my point was about what I see as "read or timeout", a reasonable functionality to expose as a external facing function. The question is still "If I want to read or timeout, from inside a function I expose in a library that uses sans-IO style, how do I do that?". It seems like the answer is "if you want to accomplish read or timeout at the library function level, you either busy wait or pull in an async runtime, but whatever calls your state machine has to take care of that at a higher level". You see
Read the rest
how this doesn't really work for me? Now I have to decide if my read_or_timeout() function exposed is either the default sync (and I have to figure out how long to wait, etc), or async. It seems in sans-IO style read_or_timeout() would be sync, and do the necessary synchronous waiting internally, without the benefit of being able to run other tasks from unrelated state machines in the meantime. > That entire `main` function is _not_ what you would expose as a library. Disagree -- it's entirely reasonable to expose "read your public IP via STUN" as a library function. I think we can agree to disagree here. > The event loop should always live as high up in the stack as possible, thereby deferring the use of blocking or non-blocking IO and allowing composition with other sans-IO components. Sure... but that means the code you showed me should never be made into a library (we can agree to disagree there), and I think it's reasonable functionality for a library... What am I missing here? From unrelated code, I want to call `get_ip_via_stun_or_timeout(hostnames: &[String], timeout: Duration) -> Option<String>`, is what I'm missing that I need to wrap this state machine in another to pass it up to the level above? That I need to essentially move the who-must-implement-the-event-loop one level up? > You can absolutely write an event loop without async. You can set the read-timeout of the socket to the value of `poll_timeout() - Instant::now` and call `handle_timeout` in case your `UdpSocket::recv` call errors with a timeout. str0m has an example [1] like that in their repository. Didn't say you couldn't! What you've described is looping with a operation-supported timeout, which requires timeout integration at the function call level below you to return control. I get that this is a potential solution (I mentioned it in my edits on the first comment), but not mentioning it in the article was surprising to me. The code I was expecting to find in that example is like the bit in strom: https://github.com/algesten/str0m/blob/5b100e8a675cd8838cdd8... Clearly (IMO evidenced by the article using this method), the most ergonomic way to do that is with a tokio::select, and that's what I would reach for as well -- but I thought a major point was to do it sans IO (where "IO" here basically means "async runtime"). Want to note again, this is not to do with the state machine (it's clear how you would use a passed in Instant to short circuit), but more about the implications of abstracting the use of the state machine. > All the event loops you see in the post are solely there to ensure we have a working program but are otherwise irrelevant, esp. implementation details like using `tokio::select` and the like. Perhaps I should have made that clearer. I personally think it exposes a downside of this method -- while I'm not a fan of simply opting in to either async (and whichever runtime smol/tokio/async-std/etc) or sync, what it seems like this pattern will force me to: - Write all code as sync - Write sync code that does waiting based on operations that yielding back control early - Hold my own tokio runtime so I can do concurrent things (this, you argue against) Async certainly can be hard to use and have many footguns, but this approach is certainly not free either. At this point if I think I want to write a library that supports both sync and async use cases it feels like feature flags & separate implementations might produce an easier to understand outcome for me -- the sync version can even start as mostly `tokio::Runtime::block_on`s, and graduate to a more performant version with better custom-tailored efficiency (i.e. busy waiting). Of course, I'm not disparaging the type state pattern here/using state machines -- just that I'd probably just use that from inside an async/sync-gated modules (and be able to share that code between two impls).
In Sans-IO: The secret to effective Rust for network services
> If I want to write a function that listens or times out in sans-IO style, should I use tokio::select? If so, where is the async runtime coming from, and how will the caller of the function be able to avoid caring? To "time-out" in sans-IO style means that your state machine has an `Instant` internally and, once called at a specific point in the future, compares the provided `now` parameter with the internal timeout and changes its state accordingly. See [0] for an example. > but is absolutely the domain of a random library function that you might want to expose. That entire `main` function is _not_ what you would expose as a library. The event loop should always live as high up in the stack as possible, thereby deferring the use of blocking or non-blocking IO and allowing composition with other sans-IO components. You can absolutely wri
Read the rest
te an event loop without async. You can set the read-timeout of the socket to the value of `poll_timeout() - Instant::now` and call `handle_timeout` in case your `UdpSocket::recv` call errors with a timeout. str0m has an example [1] like that in their repository. > It's a bit jarring to introduce the concept as not requiring choices like async vs not, then immediately require the use of async in the event loop (required to drive the state machine to completion). All the event loops you see in the post are solely there to ensure we have a working program but are otherwise irrelevant, esp. implementation details like using `tokio::select` and the like. Perhaps I should have made that clearer. [0]: https://github.com/firezone/firezone/blob/1e7d3a40d213c9524a... [1]: https://github.com/algesten/str0m/blob/5b100e8a675cd8838cdd8...
In Sans-IO: The secret to effective Rust for network services
What makes something a 'blessed way'? Are you looking for community support, large corporate users etc..? Not being snarky, curious about how people see the space. Lots of implementations exist and I have used most of them for different projects, not all these projects went to production though. * https://github.com/elixir-webrtc (Elixir) * https://github.com/pion/webrtc (Golang) * https://github.com/webrtc-rs/webrtc (Rust) * https://github.com/algesten/str0m (Rust) * https://github.com/sepfy/libpeer (C/Embedded) * https://github.com/awslabs/amazon-kinesis-video-streams-webr... (C/Embedded) * https://github.com/paullouisageneau/libdatachannel (C++) * https://webrtc.googlesource.com/src/ (C++) * https://github.com/shinyoshiaki/werift-webrtc (Typescript) * https://github.com/sipsorcery-org/sipsorcery (C#) * https://github.com/aiortc/aiortc
Read the rest
(Python) * GStreamer’s webrtcbin (C)
In VoRS: Vo(IP) Simple Alternative to Mumble
libdatachannel[0] is exciting me the most for 'low footprint'. str0m[1] is especially exciting, but you have to be in a device/ecosystem that allows rust. > only if you use the same kind of software and codecs With WebRTC I can connect clients with varying support of H264, VP8, VP9, AV1, Opus, ulaw and alaw. WebRTC has plenty of flaws, but 'lack of negotiation' is one of them. [0] https://github.com/paullouisageneau/libdatachannel [1] https://github.com/algesten/str0m
In VoRS: Vo(IP) Simple Alternative to Mumble
Sure! I mentioned a few orthogonal concepts that go well together, and each of the following examples has a different combination that they employ: - the company that developed Madsim (RisingWave) [0] [1] is tries hardest to eliminate non-determinism with the broadest scope (stubbing out syscalls, etc.) - sled [2] itself has an interesting combo of deterministic tests combined with quickcheck+failpoints test case auto-discovery - Dropbox [3] uses a similar approach but they talk about it a bit more abstractly. Sans-IO is more documented in Python [4], but str0m [5] and quinn-proto [6] are the best examples in Rust I’m aware of. Note that sans-IO is orthogonal to deterministic test frameworks, but it composes well with them. With the disclaimer that anything I comment on this site is my opinion alone, and does not reflect the company I wor
Read the rest
k at —— I do work at a rust shop that has utilized these techniques on some projects. TigerBeetle is an amazing example and I’ve looked at it before! They are really the best example of this approach outside of FoundationDB I think. [0]: https://risingwave.com/blog/deterministic-simulation-a-new-e... [1]: https://risingwave.com/blog/applying-deterministic-simulatio... [2]: https://dropbox.tech/infrastructure/-testing-our-new-sync-en... [3]: https://github.com/spacejam/sled [4]: https://fractalideas.com/blog/sans-io-when-rubber-meets-road... [5]: https://github.com/algesten/str0m [6]: https://docs.rs/quinn-proto/0.10.6/quinn_proto/struct.Connec...
In Is something bugging you?
I am really excited about https://github.com/sepfy/libpeer. It has examples ready for ESP32 etc.... When working on KVS I wasn't familiar with the embedded space at all. I saw 'heavyweight' embedded where you were running on Linux. Then you had RTOS/No OS at all. I wasn't prepared for these devices at all. If we can make WebRTC work in the embedded space I think it will really accelerate what developers are able to build! Remotely driven cars, security cameras, robots in hospitals that bring iPads to infectious patients etc... Creative people are building amazing things. The WebRTC/video space needs to work harder and support them :) ----- I love how diverse the WebRTC space is now. Outside of this implementation you have plenty of other options! * https://github.com/shinyoshiaki/werift-webrtc (Typescript) * https://github.com/pion/webrtc
Read the rest
In Pure C WebRTC
What libraries have you used? There are a lot these days, maybe you haven't tried one yet that matches the way you think/code :) * https://github.com/aiortc/aiortc (Python) * GStreamer’s webrtcbin (C) * https://github.com/shinyoshiaki/werift-webrtc (Typescript) * https://github.com/pion/webrtc (Golang) * https://github.com/webrtc-rs/webrtc (Rust) * https://github.com/algesten/str0m (Rust) * https://github.com/awslabs/amazon-kinesis-video-streams-webr... (C/Embedded) * hhttps://github.com/sepfy/libpeer (C/Embedded) * https://webrtc.googlesource.com/src/ (C++) * https://github.com/sipsorcery-org/sipsorcery (C#) * https://github.com/paullouisageneau/libdatachannel (C++) * https://github.com/elixir-webrtc (Elixir) See https://github.com/sipsorcery/webrtc-echoes for examples of some running against each other.
In WebRTC for the Curious (2020)
If you want to do servers or embedded you shouldn’t. It makes sense to use in the places it was designed for though! If you are shipping a client and have needs that match its creators it’s the best choice. What features of libwebrtc in particular would you like to see in other implementations. I am very excited to see a future with [0] on the client side. [0] https://github.com/algesten/str0m
In WebRTC for the Curious (2020)
Really exciting times for WebRTC in general right now! If you are new to WebRTC and want to learn more about the protocol check out [0] (would love peoples feedback). It is used in lots of unexpected places like streaming (added to OBS)[1] and Embedded [2]. I am especially excited with new implementations popping up like [3] and [4]. [0] http://webrtcforthecurious.com [1] https://github.com/Glimesh/broadcast-box [2] https://github.com/sepfy/libpeer [3] https://github.com/algesten/str0m [4] https://github.com/elixir-webrtc/ex_webrtc
In Show HN: Bring phone calls into the browser (SIP-to-WebRTC)

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.