Setup
Add the crate for Linux, register the plugin, and grant webrtc:default to the windows that make calls.
Dependency
Depend on the plugin for Linux only. On macOS and Windows the webview has native WebRTC, and the plugin has no engine there.
[target.'cfg(target_os = "linux")'.dependencies]
tauri-plugin-webrtc = { git = "https://github.com/crabnebula-dev/tauri-plugin-webrtc", branch = "main" }
Features
The plugin's features forward to qrtc's.
| Feature | Default | Effect |
|---|---|---|
turn-tls-ring | yes | TURN over TLS (turns:) with rustls on ring, which compiles C and assembly |
turn-tls-rustcrypto | no | TURN over TLS with rustls on RustCrypto; pure Rust, pre-release provider |
pq-moduletto | yes | Post-quantum key agreement with moduletto ML-KEM |
pq-hybrid | no | Post-quantum key agreement with RustCrypto ml-kem |
A build with no C at all:
tauri-plugin-webrtc = { git = "https://github.com/crabnebula-dev/tauri-plugin-webrtc", branch = "main",
default-features = false, features = ["turn-tls-rustcrypto", "pq-moduletto"] }
Without a TLS feature, turns: servers are skipped. Without a post-quantum feature, DTLS stays at 1.2 and postQuantum other than "off" fails.
Registering the plugin
#[cfg(target_os = "linux")]
{
builder = builder.plugin(tauri_plugin_webrtc::init());
}
init() uses the defaults. For other settings, use the builder:
builder.plugin(
tauri_plugin_webrtc::Builder::new()
.max_peers_per_webview(8)
.build(),
)
| Option | Default | Effect |
|---|---|---|
max_peers_per_webview(n) | 16 | Cap on concurrent peer connections per webview. Past the cap, the new connection's methods reject with an OperationError. |
force_shim(true) | off | Installs the shim even over a native RTCPeerConnection. For testing the shim in a webview that has WebRTC. |
engine(arc) | qrtc | Any other implementation of qrtc's PeerEngine trait. |
If the engine cannot start, the plugin logs a warning and the shim stays out, so the page sees no WebRTC rather than a broken one.
Permissions
webrtc:default grants three sets. Grant sets on their own to narrow what a window may do.
| Set | Commands |
|---|---|
webrtc:allow-peer | Create, negotiate, add candidates, stats, ICE restart, close |
webrtc:allow-data | Create, send on and close data channels; buffered amount and threshold |
webrtc:allow-media | Transceivers, keyframe requests, transforms, DTMF, audio processing, media and audio frames |
Camera, microphone and screen capture are not part of these. They stay with the webview's own getUserMedia and its permission handling.
Lifecycle
- Peer connections belong to the webview that created them.
- They close when the page navigates, when its window is destroyed, and when the plugin is dropped.
pc.close()in the page closes one at once.
Detecting the shim
RTCPeerConnection.__tauriShim is set when the plugin installed the classes. It holds the engine name. The marker is also on the prototype, so it survives wrappers such as webrtc-adapter.
const shim = RTCPeerConnection.prototype.__tauriShim; // { level: 'L3', engine: 'native-str0m' } or undefined