Advanced Native
Use OpenRTC directly from Rust or project it into a Tauri WebView
Native Rust does not depend on TypeScript. The openrtc crate can own the
complete native endpoint and peer lifecycle by itself. Tauri adds an optional
IPC adapter so a WebView can use that same Rust owner through the familiar
TypeScript API.
pure Rust app ────────────────┐
├─> one native openrtc::Client ─> Iroh
Tauri WebView ─> plugin IPC ──┘
There is no WASM runtime in the Tauri path and no second frontend connection manager.
Tauri WebView
Use the native-only npm entrypoint so the bundler can omit the WASM loader and binary:
import { OpenRTC } from 'openrtc/native';
import { createBridge } from 'openrtc-tauri/ipc';
const rtc = OpenRTC({ apiKey, auth }, createBridge());
const devices = await rtc.devices.start({ auth, autoConnect: 'online' });
The openrtc-tauri-plugin crate owns the native client and exposes bounded IPC
commands for capabilities, connection projections, protected messages,
streams, and media. Private key material stays in host secure storage and never
enters the WebView.
use openrtc_tauri_plugin::{
OpenRtcTauriConfig,
OpenRtcTauriState,
};
use std::sync::Arc;
let state = OpenRtcTauriState::new(OpenRtcTauriConfig {
api_key,
data_dir: None,
transport_config: Some(transport_config),
})
.with_native_device_key_signer(Arc::new(AppDeviceSigner));
// Product-native Rust features may use this exact same client.
let openrtc_client = state.client();
tauri::Builder::default()
.manage(openrtc_client)
.plugin(openrtc_tauri_plugin::init_with_state(state))
.run(tauri::generate_context!())?;
Add openrtc-tauri-plugin:default to the Tauri capability that owns the
OpenRTC WebView. Without the plugin or permission, the native frontend fails
closed instead of silently starting a browser runtime.
Pure Rust
Pure-Rust consumers use ControlPlane::anonymous(apiKey, signer) for
backend-free spaces, ephemeral rooms, and tickets, or ControlPlane::new
with their assertion, secure signer, protected certificate store, and optional
enrollment-attestation providers for authenticated devices. These high-level
methods issue and renew bounded capabilities and grants; the returned handle
owns exactly one avenue and exposes signaling() plus idempotent close().
use openrtc::{
Client,
native::{CapabilityOptions, ControlPlane, DeviceSigner},
};
use std::sync::Arc;
let signer: Arc<dyn DeviceSigner> = app_secure_signer();
let control = ControlPlane::anonymous(API_KEY, signer)?;
let room = control.join_room(
"call-123",
"desktop",
CapabilityOptions::default(),
).await?;
let client = Arc::new(
Client::builder(API_KEY.to_owned(), Box::new(|| None))?
.signaling_backend(room.signaling())
.build(),
);
client.send_peer(peer_id, b"hello").await?;
room.close().await;
Authenticated device meshes additionally supply the provider-neutral
AssertionProvider, DeviceSigner, and CertificateStore traits. The app
keeps its identity-provider SDK and private key storage outside OpenRTC.
Native media uses encoded MediaSource and MediaSink implementations supplied
by the host. Native streams use Client::open_peer_bi(), open_peer_uni(), and
the datagram methods. No DOM, JavaScript promise, browser WebRTC session, or MoQ
session type crosses the Rust API.
See Avenues for devices, spaces, rooms, and ticket examples.
Lower-level composition
Client::new(apiKey) and new WasmClient(apiKey) are side-effect-free
compiled-runtime constructors. The TypeScript capability layer owns browser
assertion exchange and IndexedDB/WebCrypto install keys, while the Rust control
plane owns the equivalent native exchange. Client::new_provider_neutral is an
internal composition surface for hosts that already own a reviewed grant
provider; it is not the normal consumer quickstart.
Advanced browser hosts using the generated binding directly may call
WasmClient.setRelay(enabled) before initIroh(). Calling it after endpoint
initialization fails because relay discovery cannot be changed truthfully on a
running endpoint. Normal applications should configure
OpenRTC({ transports: { relay: false } }); the TypeScript bridge applies the
WASM setting before initialization.
Do not relay consumer Firebase credentials into Rust as the OpenRTC identity contract. The application supplies a provider-neutral assertion; optional platform attestation is enrollment evidence rather than a recurring connection token.
Host-reported compiled capabilities determine native Iroh, WebRTC, MoQ, LAN, and BLE availability.
Offline edge enrollment
client.offline() uses the same Rust endpoint and host-owned signer. It does
not require TypeScript, the coordination gateway, or a public relay. Configure
the client with NetworkPolicy::LocalOnly before endpoint startup and compile
the transport-lan feature. See Offline edge devices
for the enrollment request and trust model.