You follow a WebRTC tutorial. You open two browser tabs. Camera turns on. Video streams. Life is good.
You deploy it.
Nothing works.
No video. No connection. No errors that make sense.
If this has happened to you, you didn't do anything wrong.
Localhost is cheating you.
Why Everything Works on Localhost
When you test WebRTC on your own machine, you're in the easiest networking environment possible: same laptop, same browser, same Wi-Fi, same router, no firewalls in the way.
Your computer already knows how to reach itself. So WebRTC barely has to try.
That's why tutorials look magical.
But the moment you involve a phone, a friend's laptop, a different network, or the internet at large, the magic disappears.
The Moment Reality Hits
Try any of these:
- One peer on mobile data
- One peer behind college Wi-Fi
- One peer behind a corporate firewall
- Deploying the app over HTTPS
Suddenly:
- Connections hang forever
- Video never appears
- Peers "connect" but send nothing
And most tutorials stop right before explaining why.
What Tutorials Usually Skip
They don't skip it because it's unimportant. They skip it because it's messy.
This is where WebRTC stops being a demo and starts being real networking.
Signaling: How Peers Even Find Each Other
WebRTC is peer-to-peer, but peers don't magically discover each other. They need help. They need some server, any server, just to exchange connection details.
Most tutorials cheat by:
- Copying text between tabs
- Hard-coding values
- Assuming both sides are already connected
That works on localhost. It fails everywhere else.
Why "It Connects on My Laptop" Means Nothing
On real networks:
- Your laptop is behind a router
- Your phone is behind carrier NAT
- Your friend is behind another router
- Firewalls block random ports
So the connection needs fallback paths. That's where things like ICE, STUN, and TURN quietly decide whether your app works or dies.
You don't notice them on localhost because you don't need them there.
HTTPS Isn't Optional Anymore
Another silent trap: browsers trust localhost. They do not trust random HTTP websites.
Camera access, mic access, screen sharing, WebRTC data channels, all require a secure context. So your app works locally and breaks the moment you deploy it.
Again: not your fault.
What "Real" WebRTC Actually Requires
Not theory. Just reality:
- A way for peers to exchange connection info
- A way to deal with different networks
- A fallback when direct connections fail
- HTTPS in production
Once you accept that, WebRTC stops feeling random. It becomes predictable.
The Localhost Illusion
When you open two tabs on the same machine:
- Same IP
- Same NAT behavior
- Same firewall rules
- Same browser process
This creates an environment where all ICE candidates are trivially reachable, and the browser happily connects the two peers without any real networking challenges.
In other words: it's not WebRTC working - it's your machine shortcutting the network problems.
So, what exactly are we skipping?
1. SDP Exchange - Not Magic, Just Signaling
WebRTC itself doesn't provide any way to exchange session information, that's up to you.
The Session Description Protocol (SDP) contains:
- Supported codecs
- Media direction
- ICE candidates (IPs and ports)
- DTLS keys
In tutorials, developers often hard-code or manually copy/paste SDPs because there's no signaling server in the demo.
But in real apps, you need reliable signaling server to:
- Exchange offers and answers
- Deliver ICE candidates as they arrive
- Handle renegotiation
- Manage disconnects/fallbacks
No signaling = no connection. Period.
2. ICE Candidates - Behind the Scenes Networking
When a peer creates an offer or answer, WebRTC generates multiple ICE candidates:
- Host: Direct machine IPs (e.g., 192.168.x.x)
- Server Reflexive: Public IP discovered via STUN
- Relayed: TURN server addresses
On localhost, only host candidates exist and they work perfectly.
But on real networks:
- Local IPs are never reachable from outside your network
- NAT traversal becomes mandatory
- Firewalls block direct UDP
- Connections stall without TURN
Many tutorials stop after the first SDP exchange, never showing how to gather and exchange ICE candidates properly.
3. STUN / TURN - The Invisible MVPs of WebRTC
STUN (Session Traversal Utilities for NAT)
STUN lets a peer discover its public IP and port as seen from the internet.
This is critical when:
- Peers are on different networks
- Behind NATs
- Connecting across the internet
Without STUN, WebRTC only offers your local IPs - useless for remote peers.
TURN (Traversal Using Relays around NAT)
TURN servers relay media when direct peer-to-peer fails.
- Firewall blocks UDP?
- Symmetric NATs?
- Enterprise networks?
Media goes through TURN.
TURN servers are neither optional nor cheap:
- Bandwidth costs money
- You must self-host or pay for a provider
- Most localhost demos never mention TURN
4. HTTPS - It's Not a Suggestion
WebRTC requires secure contexts:
- HTTPS
- Localhost
- Browser allowed flags (only for dev)
Webcam, mic, screen capture, WebRTC data channels, all require HTTPS in real usage.
If your app runs over HTTP:
- No media
- No device permissions
- No WebRTC support
Localhost is exempted by browsers - yet another reason demos work locally but implode in production.
5. NAT & Firewalls - Where Theory Meets Reality
Real world networking throws real problems:
- Home router NAT
- Carrier-grade NAT
- Corporate firewalls
- Mobile hotspots
- VPNs
These often break direct peer connections. Only through full ICE gathering and a reliable TURN server can your app succeed consistently.
Why I Built This Demo
Live demo: https://p2p-vision-web.vercel.app/
Source: https://github.com/abhiram-karanth-core/p2p-vision-web
This project isn't meant to look impressive on localhost. It's meant to survive:
- Different devices
- Different networks
- Real deployments
Because that's where WebRTC usually breaks.
Takeaway
If your WebRTC app only works on localhost, it doesn't work yet.
Localhost removes:
- Network boundaries
- NAT
- Firewalls
- Security rules
The real world adds them back.
And WebRTC makes you deal with all of it - whether tutorials mention it or not.
Comments are open. Agree, disagree, or add your war story.
Top comments (0)