WebRTC over QR

This is a project exploring how close we can get to a truly Peer-to-Peer WebRTC experience: just a single offline HTML file on the host, bootstrapped onto the guest via <2,953 bytes of HTML squeezed into a single QR code (plus a return QR code is required for some browser engines). No servers in the middle, just two web browsers speaking WebRTC and JavaScript to each other.

Please read the caveats below before trying it out! It is incredibly cool that it is even possible, and even somewhat portable between browsers (though Chromium works best), and I have done my best to smooth out the rough edges to make it pleasant to use. The concept underlying the connection procedure is relatively simple, and I have written a chat app on top to demonstrate its usefulness and test aspects like latency (try running /ping).

More information and downloads at https://webrtc-over-qr.veritates.love/.


Try it!

The instructions for using it with another device (e.g. hosting on a computer and joining as a guest with a phone) are on the page.

You may also use it on its own, either in side-by-side mode or echo/loopback mode (both modes still go over WebRTC).

Blog Posts

Code

The code repository is currently at MonoidMusician/webrtc-over-qr on GitHub.

The only dependency is the QR code library, which is ZXing-JS (“Zebra Crossing”), and provides QR code generation and scanning on the host. My only modification to it was to remove features that I do not use and then re-bundle it, to reduce the size.



Caveats

  • WebRTC discovery works differently across browser engines. Chromium-based browsers give the nicest experience: we are able to auto-discover guests when they open the page and try to connect. On other engines (like Safari and Firefox), the certificate fingerprint generated by the guest must be sent back to the host via some other method (QR code, copy+paste, instant message, verbal transcription, etc.).

    Our mode of connection (entirely peer-to-peer) is somewhat unintended, as WebRTC was designed to have a (trusted!) signaling server mediate a connection. Thus there is no uniform experience we can offer, although we can try our best and add workarounds for these situations.

  • Firefox behaves very differently based on the flag media.peerconnection.ice.obfuscate_host_addresses in about:config (which is set to true by default). In particular, it seems to impose a ~5 second timeout as guest. And as host, it will not connect to a Chromium guest? So you might want to set this to false while trying the demo, or use a different browser instead. Note that it is a global setting, so remember to set it back to the default true when you are done.

  • While we produce standards-compliant QR codes, they aren't exactly usable by existing software: the QR code generated by the host contains a data URI, which most phone apps will not recognize as a link, and even if they do, browsers will not open data URIs from external sources (or in the case of Firefox on iOS, ever at all), so you may have to use a different QR code scanner and copy and paste the URL into a browser. And on the flip side, the QR code generated by the guest is 32 bytes of raw binary data, which most scanners will not even display for you, and would not be safe to copy as text. However, this is less of an issue since we can embed a QR scanner here in secure contexts (HTTPS, localhost, and apparently local files too).

  • A lot of nice web APIs understandably do not work in insecure contexts. This experiment of bootstrapping a peer-to-peer web chat over QR is not secure and there is not much we can do about it. This means no access to webcams or microphones, no popup notifications, etc., at least from the guest. But there is still a lot of amazing things that we can do, things that any (web) chat app could have done but didn't.

  • The demo has no way of reestablishing a connection if it drops (I do not know if it would be technically possible at all without manually passing information between the peers again ... you could at least pre-establish the certificates to use). The demo also does not use STUN or TURN servers, which facilitate connections behind NAT/firewalls, so it may only work between devices on your local network.