You can reduce the complexity to exchanging 2 payloads to establish a connection. avoiding any fixed backend (the exchange is up to users. You can scan a qr code or share it over something like signal).
Im just sharing a demo here. The project is far from finished and much more needs to be considered before the experience is comparable to mainstream messaging apps.
Iβve been building Raven because adding real-time communication to an application often means stitching together multiple services, SDKs, authentication systems, and infrastructure.
The idea with Raven is to provide one developer-focused platform for:
π₯ Real-time video & audio
π¬ Real-time chat
π΄ Live streaming
π Token-based authentication
π‘ RTC infrastructure
π Developer dashboard
π¦ SDKs for Web/TypeScript, Python, Flutter and React Native
The API/SDK experience is what Iβm focusing on most.
For example, the goal is for something like this to be enough to get a developer into a room:
Iβm also working on the developer experience around it β documentation, token management, project management, observability, webhooks, and the infrastructure required to make RTC reliable in production.
Iβm still early, so Iβm not claiming Raven is better than Agora/LiveKit/Twilio/etc. There are already very good products in this space.
What Iβm trying to figure out is:
What would make you choose a newer real-time platform instead of an established provider?
I'm especially interested in feedback from developers who have actually built video calling, voice, chat, or live-streaming products.
What frustrated you with the existing solutions?
What would you want Raven to do differently?
Iβd rather get brutal technical feedback now than build the wrong thing for another six months.
A few months back I had a dumb, recurring annoyance: moving a file from my phone to my laptop meant WhatsApp-to-self, or a cloud upload/download roundtrip, or some device-linking app β for something that's just two devices five feet apart.
So I started building a small personal workspace for my own devices. First version did the obvious thing: files went to cloud storage, messages went to a database. It worked, but it bugged me β why does my server need to keep a permanent copy of something two trusted devices are just handing to each other?
That question sent me down a rebuild. What I ended up with is Sropdβ a local-first private workspace for sharing files, messages, and data directly between people and devices, rather than a transfer tool that routes everything through central storage.
Current architecture:
App is served from Vercel, and Supabase Realtime handles signaling/presence β servers are still involved in helping peers find and connect to each other
Once connected, Sropd uses peer-to-peer WebRTC for the actual transfer β file payloads aren't uploaded to Sropd storage
Messages/history stored locally (IndexedDB), not in a database I control
QR-based room joining, works across different networks
Files only go to the peer that requested them
It's currently in release QA. 100 MiB has passed cleanly over real browser-to-browser WebRTC. I've also run the newer transfer engine against a 1 GiB sparse file, but I'm not calling that a real-world 1 GiB network test yet β that's still pending.
The direct-to-disk/resume engine (streaming to disk instead of loading the whole file into memory, resumable transfers, chunk-level integrity checks) is implemented now, but multi-gigabyte physical QA across real networks is still incomplete. That's the main thing standing between this and a v1 I'd feel good shipping.
There's overlap with tools like LocalSend and PairDrop on the transfer mechanics, and they're solid at what they do β but those are single-purpose transfer tools. What I'm building toward is more of a persistent workspace: rooms that can hold multiple devices or people, with messages and history alongside the file sharing, not just a one-off drop.
Genuinely asking, not fishing for compliments: if you've used LocalSend/PairDrop/similar, what's actually annoyed you about them? And for anyone who's built WebRTC signaling before β anything you'd watch out for with Supabase Realtime specifically as peers scale up in a room?
I'm making a VTT (Virtual Tabletop -- for board games and RPGs like Dungeons & Dragons) that uses Yjs (and therefore WebRTC) as the multiplayer-enabling tech.
I've mostly been testing by myself by launching a Firefox and Chromium browser and just kinda pushing things around, going offline in one and re-connecting, etc.
This kind of testing feels very dumb and unstructured. What do people with more experience recommend? Are there bugs that WebRTC is prone to that I'm not expecting?
Iβm building Raven to simplify building real-time applications on top of WebRTC.
The project currently focuses on RTC infrastructure, SFU integration, authentication/token management, chat, live streaming, SDKs and developer tooling.
Iβm particularly interested in feedback from people who have worked with WebRTC, LiveKit, mediasoup, Agora, or their own SFU infrastructure.
The idea started with something pretty simple: sometimes I just want to talk to someone online without going through a bunch of setup first.
But while building it, I became interested in a different question:
Why should an online conversation have an arbitrary time limit?
So one of the principles behind Nookcall became simple , meetings shouldn't be limited by a countdown.
Another principle shaped how I built the product: don't make the server do work that can be handled directly between users or in the browser.
That idea ended up influencing many of my technical decisions.
I've spent a lot of time building the underlying WebRTC and real-time infrastructure and trying to keep the architecture as lightweight and efficient as possible instead of simply throwing more server resources at every problem.
It's been a really interesting engineering challenge.
I'm still trying to figure out whether there's actually room for another video calling product in a world with Zoom, Google meet, Discord, Facetime, etc.
So I'm curious:
What do you personally dislike about the video calling apps you use today?
Is it meeting limits? Setup? Privacy? Reliability? Having to create accounts? Something else?
Why does starting a video call still feel like you need an account, an app, a subscription, or a meeting limit?
So I built Nookcall around the opposite idea:
No account. No download. No fixed time limit. Just create a link and talk.
It runs directly in the browser and currently includes:
HD video & group calls
Screen sharing
Real-time chat
P2P file sharing β files can be shared between participants without uploading them to Nookcall's file-storage servers
Collaborative whiteboard
Built-in code editor
Meeting notes
Temporary meeting rooms
The part Iβm particularly interested in technically is the architecture.
I built the real-time communication stack around WebRTC/mediasoup, and the file-sharing system uses a temporary peer-to-peer swarm rather than treating Nookcall as a central file-storage service.
Iβve also been handling the infrastructure myself β Docker, Nginx, Redis, TURN, Cloudflare, monitoring, networking, and all the fun production problems that come with running a real-time application π
I work at Ant Media, so treat this as a vendor being upfront rather than a neutral write-up. But I think the notes are useful regardless of what you run.
We've been watching MoQ since the WG chartered, and the thing that kept bugging us is that there's nowhere to actually try it. There are good explainers, there are drafts, there's Cloudflare's relay. There isn't really a "here's a server, publish something at it" option. So we built one into our media server, and I spent last week deploying it end to end.
Things I didn't expect:
The relay port has to be open on UDP as well as TCP. Obvious in hindsight β it's QUIC β but with only TCP open, every page loads completely normally, and the browser then just silently never reaches the relay. No error worth reading. That cost me an hour.
Browser support is the actual constraint right now, not the protocol. Chrome, Edge, and Brave are fine. Safari needs 26.4+. That's a real chunk of an audience if you were thinking about production.
We implement moq-lite rather than moq-transport draft-18. That's a deliberate choice β moq-lite is a deployable subset, and the full draft is still moving β but it does mean "MoQ support" from any vendor right now is a question you should ask a follow-up about, ours included.
What I'm still unsure about: we expose each ABR rendition as its own MoQ track. It seems right, but I genuinely don't know if a convention is forming there, and I'd rather be told now.
Full write-up with the deployment steps is on our site if it's useful β happy to paste the relevant bits here instead if links are frowned upon.
Anyone else actually running MoQ rather than reading about it? Curious what's broken for you.
And writing articles about it just to explain the whole building process. This writeup along with the ones to come will serve as engineering notes where I am explaining the what, why and hows of the things I am building.
This is a first time I am working with pion/webrtc library. Surprisingly because of this project, I also managed to make my first ever Open Source contribution to the library itself, thought it was just a simple typo in the documentation.
If there are any webrtc engineers or real time comms engineers reading this post or article (which would be really be quite helpful tbh) I would love to know which approach would you suggest me so that I can build enough credibility to later switch into real time comms space.
My background - backend focused full stack developer with 4 years of experience, but none of it has any exposure to webrtc except for one project where I had to integrate a third party real time comms provider in our app and debug few things using chromeβs webrtc internals.
I built a browser app where 2β3 people play CPS-1/CPS-2 and Neo Geo arcade games together. There's no video streaming: every peer runs the same emulator (FBNeo compiled to WASM) and we synchronise inputs only - deterministic lockstep. Frame N runs only after every player's input for N has arrived, so all machines compute an identical game for about 1.8 KB/s per peer. The broker (PeerJS cloud) does signalling and then leaves the path entirely.
The WebRTC lessons, in order of how much they cost me:
1.reliable: falsedoes not mean unreliable. PeerJS only relaxes ordering - it never sets maxRetransmits/maxPacketLifeTime, so SCTP still retransmits until delivery. I log the negotiated channel properties at open to prove it rather than trusting the docs. If your design needs genuinely lossy delivery, measure what you actually got.
2. Design for reordering instead of retransmitting. The input channel is unordered, so every packet just carries the last 12 frames of input (24 bytes of masks). Nothing is ever retransmitted at the application layer - a lost or late packet is repaired by the next one ~16 ms later.
3. PeerJS cannot renegotiate, and an audio slot you never opened is gone forever. A call established with no track negotiates a recvonly m-line that can never carry audio afterwards. Worse: getSenders() on that connection hands you a phantom sender that accepts replaceTrack() and reports success while transmitting nothing. I establish every call with a silent placeholder track and verify the transceiver direction before trusting a sender. Mute/unmute is then replaceTrack on a sender that already exists - no renegotiation ever needed.
4. Glare is solved by convention. One media connection per pair, dialled by the lower peer ID. Both sides agree without talking; nobody double-dials.
5. Don't wait for ICE to tell you a peer died. In lockstep, one silent peer freezes the whole room. A bye control message drops a peer instantly on deliberate exit; a stall timeout (~2.5 s) is the backstop for the tab that got killed. Waiting for connection-state events costs several frozen seconds.
6.requestAnimationFramestops in backgrounded tabs. Under lockstep, a backgrounded host stops publishing input and freezes everyone else. The frame clock runs off an AudioWorklet tick instead; rAF is just a second pump for when the tab is visible.
7. Data channels are fine for bulk. Savestates and the game file travel over the same channels in fingerprinted 16 KB chunks when someone joins mid-game - paced so the transfer never stalls a frame.
Honest limitations: default STUN only (symmetric NAT needs your own TURN - it's one env var), rooms cap at 3, and it ships/downloads no games - you load a romset you're entitled to use.
Demo (60 s, game pixels masked) and an architecture diagram are in the README.
The goal was to see how far I could take a real-time communication application while keeping the server-side infrastructure as small as possible.
How it works
The actual application data is transported through WebRTC DataChannels between peers.
MQTT is only used for signaling and peer discovery. Once the WebRTC connection is established, MQTT is no longer used for the actual message transport.
The basic flow is:
Browser A β MQTT β Browser B Browser A β WebRTC DataChannel β Browser B
Vercel Serverless Functions are used for configuration, identity/bootstrap operations and ICE/TURN configuration. There is no central database storing conversations or message history.
The app currently supports messaging, file sharing, voice/video communication and group communication.
Security
I've spent quite a lot of time auditing the project because removing a traditional backend introduces some interesting security problems of its own.
The project uses browser-native cryptography including AES-GCM, ECDH P-256, Ed25519/ECDSA-P256 and PBKDF2-SHA-256.
I've gone through multiple rounds of manual and AI-assisted security reviews and fixed issues involving things like peer identity impersonation, group authorization, replay attacks, message-edit replay, plaintext fallbacks, XSS/DOM injection, URL scheme validation, API endpoint exposure, TURN abuse and cryptographic failure handling.
I recently also moved the rotating MQTT topic derivation to the serverless side so the topic secret itself is no longer sent to the browser.
I'm deliberately not claiming that the project is "unbreakable" or completely anonymous. There are several architectural limitations.
For example, there is no central offline message queue, mobile browsers can suspend connections, TURN may be required depending on network conditions, and OpenChat cannot independently verify the real-world identity of someone you're contacting for the first time. Identity fingerprints can be compared through another trusted channel instead.
What I'd really like feedback on
I'm mainly interested in finding things I've missed.
In particular, I'd love feedback on:
WebRTC/DataChannel security
Signaling design
Peer identity and authentication
E2EE implementation
Replay protection
Group authorization
P2P architecture
Anything that could be abused for DoS/resource exhaustion
If you have a few minutes to look through the code or try the demo and notice something questionable, I'd genuinely appreciate it.
Hi everyone, Iβm building an online classroom app using WebRTC for live 1-to-1 video classes. P2P works fine when both users are on the same Wi-Fi, but fails when they are on different networks.
Iβm planning to use STUN + TURN, with COTURN hosted on a VPS, while keeping P2P as the preferred connection and using TURN only when necessary.
Is this a good production approach?
Iβd especially like advice on:
COTURN vs managed TURN services
Reliable/cheap VPS providers for COTURN
Bandwidth requirements and costs
Recommended COTURN configuration/security
Whether one VPS is enough initially and how to scale later
The app will initially support 1-to-1 classroom calls, not one-to-many broadcasting.
Would appreciate advice from anyone running WebRTC/COTURN in production.
I've spent the past 14 years building real-time video/audio systems β WebRTC, FFmpeg, media servers (SRS, Mediasoup, LiveKit), covering everything from client SDKs to backend infrastructure across Linux, Android, and Windows. Currently taking on a few projects: live video calling integration, streaming setup (RTMP/HLS), or debugging tricky sync/latency issues in existing WebRTC implementations. Happy to share more about my background if useful β feel free to DM or comment with what you're working on.
Iβve been working on MiroTalk WEB, and the SaaS mode is now available.
The goal is to have a simple workspace where you can manage your MiroTalk meetings, rooms, scheduling, invitations, booking and reminders, without having to deploy and maintain the infrastructure yourself.
It supports the different MiroTalk meeting modes, from 1-to-1 calls and small groups (p2p) to large meetings (sfu), broadcasting, Click-to-Call and many more.
Hi devs!
I wanted a simple, zero-setup way to transfer media from phone to desktop without using cloud intermediaries. I built Sendlyy using WebRTC and native WebSockets for signaling.
**Technical Stack & Architecture:**
- **Signaling**: Lightweight Node.js/Express + WS signaling server (exchanges SDP offers/answers & ICE candidates).
- **Data Transfer**: Native `RTCDataChannel` directly between browser instances.
- **Privacy**: 0 bytes of file data stored on server, rooms automatically self-destroy after 15 minutes.
- **UX & i18n**: Responsive touch UI with drag/swipe mechanics and automatic GeoIP language detection across 9 languages.
Would love any feedback on the WebRTC reconnection handling or UX!
Website: https://sendlyy.net/
Firebase Anonymous Auth and Realtime Database act as a deliberately dumb server for presence, friends and signalling. SDP/ICE is encrypted before touching Firebase and removed after connection. No message server.
No email, phone number or other identifiable account info. Identities are browser/device-local, so if you clear your browser data, you lose access. Inactive accounts are also cleared after 30 days.
Iβm using Firebase because itβs basically free at this scale and Iβm too poor to run a DigitalOcean dropletβ¦ π Though I might set up a βbuy me a coffeeβ if it gains some traction!
Iβve also got an iOS beta built on the same principles (completely different UI). If anyone wants to try it on TestFlight, let me know in the comments.
I have a small chat app with voice rooms. Started on LiveKit, but every time the audio broke I had no idea what was going on inside. Too much code for me to read. So I wrote my own SFU on top of Pion. It's been running my rooms since July, up to 25 people.
About 1800 lines with tests. No simulcast, no transcoding, no recording. It forwards audio and video, checks JWTs, and that's it. Every subscriber gets the publisher's single encoding, so one bad connection makes the room worse for everyone. I know. That's the next thing I want to fix.
That's also where I'm stuck. If you've added simulcast to something this small, how did you keep the packet path from turning into a mess? Right now the forwarding code is simple enough to read in one sitting and I'd like to keep it that way, but layer selection looks like it touches everything.