Transports
LAN, BLE, Iroh, WebRTC-carrier, and MoQ-carrier settings
OpenRTC keeps one Iroh endpoint and can replace its physical packet path when the environment allows.
| Transport | Role |
|---|---|
iroh-lan | Native direct LAN QUIC path |
iroh-quic | Native direct QUIC when available |
iroh-relay | Baseline relay path, including browser WASM |
webrtc | The current Iroh connection is physically carried by WebRTC |
ble | Native BLE iroh custom transport path |
moq | The current Iroh connection is physically carried by Draft 14 MoQ |
import { OpenRTC } from 'openrtc/native';
import { createBridge } from 'openrtc-tauri/ipc';
const client = OpenRTC({
apiKey: '<your public OpenRTC API key>',
transports: {
iroh: true,
webrtc: true,
relay: true,
ble: true,
optimizeFor: 'balanced',
priority: ['iroh-lan', 'iroh-quic', 'webrtc', 'iroh-relay'],
},
}, createBridge());
All fields are optional. Managed relay fallback is allowed by default, so most
applications should omit transports entirely. A developer can disable relay
for the whole app in the portal, while one client instance can opt out without
changing the app policy:
const rtc = OpenRTC({
apiKey,
transports: { relay: false },
});
Direct-only mode removes Iroh relay addresses and relay-backed carrier routes. Native peers may still use Iroh LAN/direct QUIC. Browser peers normally require a relay-capable path, so a direct-only browser connection can correctly fail behind restrictive NATs.
Relay policy surfaces
| Surface | Default | Contract |
|---|---|---|
TypeScript Transports.relay | true | Set false before activating an avenue to make that client direct-only. |
Rust TransportConfig.relay | true | Set false before endpoint construction; sanitization removes Iroh relay, TURN, and MoQ routes. |
WASM WasmClient.setRelay(enabled) | true | Advanced host binding; call before initIroh(). The high-level TypeScript client applies it automatically. |
App manifest features.relay | true for new and migrated apps | Server ceiling. A client cannot raise it. |
App manifest relay.maxPerHour | 600 | App-wide relay-capable gateway admissions per one-hour window; accepted values are 1–100000. |
App manifest relay.uploadMbps | 25 | App-wide measured relay ingress ceiling; accepted values are 0.1–1000. |
App manifest relay.downloadMbps | 25 | App-wide measured relay egress ceiling; accepted values are 0.1–1000. |
The effective client policy is the intersection of the app manifest and local
configuration. privacy: 'relay-only' requires effective relay access and the
high-level client fails activation when that combination is impossible.
Use privacy: 'relay-only' only when the developer manifest enables relay use.
Native hosts that compose extra application protocols register them with the
Rust endpoint/router; there is no TypeScript ownership switch for that host
integration.
ble: true is the complete application switch, not a provider installation.
The published TypeScript packages do not export a custom-transport registration
API. A native Tauri host may register a compile-time Rust
NativeTransportInstaller before plugin setup; unsupported or ordinary public
hosts report BLE unavailable and continue on the Iroh base route. The current
BLE reference host is private and physical BLE acceptance has not produced
current evidence, so BLE remains experimental rather than a public SDK support
claim. OpenRTC performs capability exchange and route promotion automatically
after admission when that host integration is present. Application code should
use the same connection and stream APIs regardless of the active transport.
The admitted base route remains usable until BLE replacement succeeds, and
OpenRTC bounds retries to three attempts per current connection generation.
For a native host that adds an ALPN or composes Iroh Docs, Blobs, or Gossip on the same endpoint, see Custom Protocols. That extension changes router composition, not OpenRTC's ownership of peer lifecycle, admission, or retry.
Selection order
OpenRTC evaluates transport policy in a fixed order:
- Apply
privacyas a hard filter. - Remove routes unsupported by the local runtime or remote peer.
- Apply
optimizeForto proven, current-generation routes. - Use
priorityas the exact tie-breaker and terminal fallback order.
The cross-platform default intent is iroh-lan, iroh-quic,
webrtc, moq, then iroh-relay. Browser runtimes automatically
skip native-only LAN and QUIC. A priority entry does not enable its mechanism;
enable the WebRTC carrier, MoQ carrier, or native BLE provider separately.
When both Iroh carriers are enabled, Rust starts only the first mutually supported candidate. A bounded terminal failure advances to the next carrier; the carriers do not race and OpenRTC does not keep a long-lived TURN allocation or MoQ subscription warm by default.
lowest-latency uses existing passive RTT observations. Native route changes
require at least a 20 ms improvement, five seconds of candidate stability, a
30-second hold on the current route, and samples no older than ten seconds.
Browser carrier selection stays deterministic because starting an inactive
carrier merely to measure it would add unnecessary traffic.
WebRTC and MoQ carriers
webrtc: true enables the custom WebRTC carrier. A moq object enables the
custom MoQ carrier. In OpenRTC configuration and diagnostics these mechanisms
are named only webrtc and moq; the retired identifiers iroh-webrtc and
iroh-moq are not aliases. Both keep the public stream/channel/media APIs on
the same logical Iroh connection and change only its physical packet path;
neither has a separate application lifecycle or implementation selector.
MoQ additionally requires relayUrl. Supply a short-lived accessToken
separately; do not place credentials in the URL. A relay that does not
negotiate moq-transport-14 is incompatible.
In relay-only mode, an Iroh WebRTC carrier is eligible only with relay-only
ICE. STUN and direct candidates are removed before the attempt. MoQ and the
ordinary Iroh relay remain eligible. If no permitted route works, connection
fails instead of silently revealing a direct peer address. This is
peer-address privacy, not anonymity from service operators or account systems.
Hosted relay limits
The developer portal owns the app ceiling. “Managed relay fallback” can disable
hosted relay use, “relay-capable admissions per app / hour” lowers the app-wide
server grant rate, and the monthly app credit cap bounds all metered
OpenRTC usage. A client may set relay: false; it cannot override a disabled
app policy or raise either server limit.
New and migrated apps default to managed relay enabled with 600 relay-capable admissions per app per hour. The existing per-principal gateway safety limit continues to apply independently.
The server counts every gateway grant while the app manifest permits relay, even when a particular client later stays direct. This conservative boundary prevents a modified client from evading the developer's limit. To remove those admissions from the relay-capable bucket for the entire app, disable “Managed relay fallback” in the portal.
Managed Cloudflare TURN credentials use an opaque app tag. OpenRTC imports ingress, egress, and concurrent connections per app in closed five-minute UTC samples. A hosted OpenRTC relay must authenticate as the relay operator, verify the signed app/session context, enforce its byte-rate ceiling, and submit monotonic interval counters. MoQ is not labeled measured without an equivalent reliable meter.