WebRTC: peer-to-peer audio, video, and data in the browser
In one line: WebRTC, together with the Media Capture and Streams API, gives the web audio and video conferencing, file exchange, and screen sharing — connections between peers can be made without special drivers or plug-ins, and often without any intermediary server once the connection is set up.
The core interfaces
Section titled “The core interfaces”RTCPeerConnectionrepresents a WebRTC connection between the local computer and a remote peer; once established and opened, media streams and/or data channels can be added to it.MediaStreamTrackrepresents a single track of media data within a stream — audio, video, or text.RTCDataChannel, added to an openRTCPeerConnection, carries arbitrary application data directly between peers alongside (or instead of) media.
Capturing local media
Section titled “Capturing local media”MediaDevices.getUserMedia() requests access to the user’s camera and microphone,
resolving with a MediaStream:
const constraints = { audio: true, video: { width: 1280, height: 720 } };const stream = await navigator.mediaDevices.getUserMedia(constraints);videoElement.srcObject = stream;navigator.mediaDevices.enumerateDevices() lists available input devices. Passing a
device’s deviceId as a bare constraint value is only a preference the browser may
override; to mandate that specific device, pass it as { exact: deviceId } instead.
Signaling is not part of WebRTC
Section titled “Signaling is not part of WebRTC”WebRTC cannot create a connection without first exchanging session information — offers, answers, and network candidates — between the two peers, and MDN is explicit that this exchange needs “some sort of server in the middle”: WebRTC does not define this signal channel itself, so it can be carried over any transport the app already has (WebSocket, an existing API, etc.). A typical flow:
const pc = new RTCPeerConnection();pc.addTrack(stream.getTracks()[0], stream);
const offer = await pc.createOffer();await pc.setLocalDescription(offer);// Send `offer` to the remote peer over your own signaling channel.The receiving peer calls setRemoteDescription() with that offer, creates its own
answer, and sends it back over the same signaling channel — after which the two
RTCPeerConnection instances negotiate media/data flow between them, often (but not
always) without any server relaying the media itself.
Where it is supported
Section titled “Where it is supported”Per MDN’s compatibility data, the RTCPeerConnection() constructor has Baseline
“Widely available” status: the feature has worked across major browsers since
September 2017.
| Browser / Platform | Support | Since | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop) | ✅ yes | 56 | high | ref | Prefixed `webkitRTCPeerConnection` supported since Chrome 23. |
| Edge (Desktop) | ✅ yes | 15 | high | ref | — |
| Firefox (Desktop) | ✅ yes | 44 | high | ref | Prefixed `mozRTCPeerConnection` supported since Firefox 22. |
| Firefox (Android) | ✅ yes | 44 | high | ref | Prefixed `mozRTCPeerConnection` supported since Firefox for Android 24. |
| Safari (macOS) | ✅ yes | 11 | high | ref | — |
Feature detection
Section titled “Feature detection”async function startCall(constraints) { if (!('RTCPeerConnection' in window) || !navigator.mediaDevices?.getUserMedia) { // WebRTC isn't available — fall back to a non-realtime path // (e.g. an upload form) instead of attempting a call. return null; } const stream = await navigator.mediaDevices.getUserMedia(constraints); const pc = new RTCPeerConnection(); stream.getTracks().forEach((track) => pc.addTrack(track, stream)); return pc;}Practical checklist
Section titled “Practical checklist”- Feature-detect both
RTCPeerConnectionandnavigator.mediaDevices.getUserMediabefore starting a call, and provide a fallback path when either is missing. - Call
getUserMedia()only in response to a context the user understands — it triggers a permission prompt for camera/microphone access, unless the browser already remembers a prior grant for your origin. - Build your own signaling channel; WebRTC does not provide one, only the connection once offer/answer/candidates have been exchanged.
- Add tracks to
RTCPeerConnectionbefore creating the offer so they’re included in the negotiated session. - Use
enumerateDevices()plus adeviceId: { exact: deviceId }constraint when you need to mandate a specific camera or microphone rather than the default device.
Where to go next
Section titled “Where to go next”- Web capabilities index — other device and network-adjacent browser APIs.
- WebTransport — another browser networking capability documented in this reference.