Convert Figma logo to code with AI

webrtc-rs logowebrtc

Async-friendly WebRTC implementation in Rust

4,982
468
4,982
8

Top Related Projects

16,088

Pure Go implementation of the WebRTC API

Janus WebRTC Server

Jitsi Meet - Secure, Simple and Scalable Video Conferences that you use as a standalone app or embed in your web application.

📡 Simple WebRTC video, voice, and data channels

13,322

Simple peer-to-peer with WebRTC.

Quick Overview

The webrtc-rs project is a Rust implementation of the WebRTC (Web Real-Time Communication) protocol, which enables real-time communication between web browsers and devices. It provides a high-level API for building WebRTC-based applications in Rust.

Pros

  • Cross-platform: The library is designed to be cross-platform, supporting Windows, macOS, and Linux.
  • Asynchronous: The library uses Rust's async/await syntax, making it easy to integrate with other asynchronous Rust code.
  • Modular: The library is divided into several modules, allowing developers to use only the parts they need.
  • Actively Maintained: The project has regular updates and a responsive community.

Cons

  • Limited Documentation: The project's documentation could be more comprehensive, especially for beginners.
  • Steep Learning Curve: Integrating WebRTC into a Rust application can be challenging, especially for developers new to both Rust and WebRTC.
  • Dependency on C/C++ Libraries: The library relies on C/C++ libraries for some low-level functionality, which can make it more difficult to deploy and maintain.
  • Lack of Feature Parity: The library may not yet have feature parity with the official WebRTC implementation in C++.

Code Examples

Here are a few code examples demonstrating the usage of the webrtc-rs library:

Establishing a WebRTC Connection

use webrtc::api::APIBuilder;
use webrtc::ice_transport::ice_server::RTCIceServer;
use webrtc::peer_connection::configuration::RTCConfiguration;
use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState;

#[tokio::main]
async fn main() {
    let api = APIBuilder::new().build();
    let configuration = RTCConfiguration {
        ice_servers: vec![RTCIceServer {
            urls: vec!["stun:stun.l.google.com:19302".to_string()],
            ..Default::default()
        }],
        ..Default::default()
    };

    let peer_connection = api.new_peer_connection(configuration).await.unwrap();

    // Add event listeners and handle signaling
    peer_connection.on_connection_state_change(|state| {
        println!("Connection state changed: {:?}", state);
        if state == RTCPeerConnectionState::Connected {
            println!("Connected!");
        }
    });

    // Perform signaling and exchange ICE candidates
    // ...
}

Sending and Receiving Data Channels

use webrtc::data_channel::data_channel_init::RTCDataChannelInit;
use webrtc::data_channel::RTCDataChannel;
use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState;

#[tokio::main]
async fn main() {
    // Establish a WebRTC connection (see previous example)
    let data_channel = peer_connection
        .create_data_channel("my-channel", &RTCDataChannelInit::default())
        .await
        .unwrap();

    data_channel.on_message(|message| {
        println!("Received message: {:?}", message);
    });

    data_channel.send("Hello, WebRTC!").await.unwrap();
}

Capturing and Sending Video

use webrtc::media::track::track_local::kind::video::RTCVideoTrackInit;
use webrtc::media::track::track_local::RTCLocalTrack;
use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState;

#[tokio::main]
async fn main() {
    // Establish a WebRTC connection (see previous example)
    let video_track = RTCLocalTrack::new(
        RTCVideoTrackInit {
            track_identifier: "video_track".to_string(),
            ..Default::default()
        },
        None,
    )
    .await
    .unwrap();

    peer_connection.add_track

Competitor Comparisons

16,088

Pure Go implementation of the WebRTC API

Pros of Pion

  • Written in Go, which offers better performance and concurrency handling compared to Rust
  • More mature project with a larger community and ecosystem
  • Extensive documentation and examples available

Cons of Pion

  • Less memory-safe than Rust-based WebRTC
  • Potentially higher memory usage due to Go's garbage collection
  • May have slightly longer compile times compared to Rust

Code Comparison

WebRTC-rs:

use webrtc::peer_connection::RTCPeerConnection;
use webrtc::peer_connection::configuration::RTCConfiguration;

let config = RTCConfiguration::default();
let pc = RTCPeerConnection::new(&config)?;

Pion:

import (
    "github.com/pion/webrtc/v3"
)

peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{})
if err != nil {
    panic(err)
}

Both repositories provide WebRTC implementations in their respective languages. WebRTC-rs offers the benefits of Rust's memory safety and performance, while Pion leverages Go's simplicity and extensive standard library. The choice between them often depends on the developer's language preference and specific project requirements.

Janus WebRTC Server

Pros of Janus-gateway

  • Mature and widely-used WebRTC server implementation with extensive features
  • Supports multiple programming languages through its REST API and WebSocket interface
  • Highly scalable and suitable for large-scale deployments

Cons of Janus-gateway

  • Written in C, which may be less accessible for developers more familiar with higher-level languages
  • Steeper learning curve compared to WebRTC-rs due to its comprehensive feature set

Code Comparison

Janus-gateway (C):

janus_plugin *create(void) {
    janus_plugin *plugin = (janus_plugin *)calloc(1, sizeof(janus_plugin));
    plugin->init = janus_echotest_init;
    plugin->destroy = janus_echotest_destroy;
    plugin->handle_message = janus_echotest_handle_message;
    return plugin;
}

WebRTC-rs (Rust):

pub async fn create_peer_connection(
    config: RTCConfiguration,
) -> Result<RTCPeerConnection> {
    RTCPeerConnection::new(config).await
}

The code snippets demonstrate the different approaches and languages used in each project. Janus-gateway uses C for low-level control, while WebRTC-rs leverages Rust's safety and modern syntax.

Jitsi Meet - Secure, Simple and Scalable Video Conferences that you use as a standalone app or embed in your web application.

Pros of jitsi-meet

  • Full-featured video conferencing solution with a complete user interface
  • Supports large-scale meetings with multiple participants
  • Includes additional features like screen sharing, chat, and recording

Cons of jitsi-meet

  • More complex setup and deployment compared to a lightweight library
  • Higher resource requirements due to its comprehensive feature set
  • Less flexibility for custom implementations or integrations

Code Comparison

jitsi-meet (JavaScript):

import { JitsiMeetJS } from 'lib-jitsi-meet';

const connection = new JitsiMeetJS.JitsiConnection(null, null, options);
connection.addEventListener(JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED, onConnectionSuccess);
connection.connect();

webrtc (Rust):

use webrtc::peer_connection::RTCPeerConnection;

let peer_connection = RTCPeerConnection::new()?;
let data_channel = peer_connection.create_data_channel("data", None)?;

Summary

jitsi-meet is a comprehensive video conferencing solution with a full user interface, while webrtc is a lower-level WebRTC implementation in Rust. jitsi-meet offers a ready-to-use platform but may be less flexible for custom integrations. webrtc provides more control over the WebRTC implementation but requires more development effort to create a complete application.

📡 Simple WebRTC video, voice, and data channels

Pros of simple-peer

  • Easier to use and more beginner-friendly
  • Provides a higher-level abstraction for WebRTC
  • Supports both Node.js and browser environments

Cons of simple-peer

  • Less flexible and customizable than webrtc
  • May not support all advanced WebRTC features
  • Written in JavaScript, which may have performance limitations compared to Rust

Code Comparison

simple-peer (JavaScript):

const peer = new SimplePeer({ initiator: true })
peer.on('signal', data => {
  // send signal data to peer
})
peer.on('connect', () => {
  peer.send('hello')
})

webrtc (Rust):

let pc = RTCPeerConnection::new()?;
let dc = pc.create_data_channel("data")?;
dc.on_open(Box::new(move || {
    dc.send_text("hello").unwrap();
}));

Both libraries provide abstractions for WebRTC functionality, but simple-peer offers a more straightforward API for basic use cases. webrtc, being a Rust implementation, provides lower-level control and potentially better performance, but requires more setup and understanding of WebRTC concepts.

simple-peer is ideal for quick prototyping and simpler applications, while webrtc is better suited for more complex, performance-critical projects that require fine-grained control over WebRTC functionality.

13,322

Simple peer-to-peer with WebRTC.

Pros of PeerJS

  • Written in JavaScript, making it more accessible for web developers
  • Simpler API, abstracting away much of WebRTC's complexity
  • Extensive documentation and examples available

Cons of PeerJS

  • Less flexible and customizable compared to WebRTC
  • Limited to browser environments, unlike WebRTC which can be used in various contexts
  • May have higher latency due to additional abstraction layer

Code Comparison

PeerJS:

const peer = new Peer();
peer.on('open', (id) => {
  const conn = peer.connect('remote-peer-id');
  conn.on('open', () => {
    conn.send('Hello!');
  });
});

WebRTC:

let peer_connection = RTCPeerConnection::new()?;
let data_channel = peer_connection.create_data_channel("data")?;
data_channel.on_open(Box::new(move || {
    data_channel.send_text("Hello!").unwrap();
}));

Summary

PeerJS offers a more straightforward approach for web developers, with a focus on ease of use and browser compatibility. WebRTC, on the other hand, provides greater flexibility and can be used in various environments beyond browsers. The choice between the two depends on the specific requirements of the project and the developer's familiarity with the respective languages and ecosystems.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

WebRTC.rs

License: MIT/Apache 2.0 Discord Twitter

Async-friendly WebRTC implementation in Rust

Sponsored with 💖 by

Gold Sponsors:
Recall.ai

Silver Sponsors:
Stream Chat
ChannelTalk
Bronze Sponsors:
AdrianEddy

Overview

WebRTC.rs is an async-friendly WebRTC implementation in Rust, originally inspired by and largely rewriting the Pion stack. The project is currently evolving into a clean, ergonomic, runtime-agnostic implementation that works with any async runtime (Tokio, async-std, smol, embassy).

Architecture:

  • rtc: Sans-I/O protocol core with complete WebRTC stack (95%+ W3C API compliance)
  • webrtc (this crate): Async-friendly API with runtime abstraction layer

📖 Learn more: Read our architecture blog post for design details and roadmap.

🚨 Important Notice: v0.17.x Feature Freeze & v0.20.0+ Development

v0.17.x is the final feature release of the Tokio-coupled async WebRTC implementation.

Current Status (February 2026)

  • v0.17.x branch: Receives bug fixes only (no new features). Use this for Tokio-based production applications.
  • Master branch: Under active development for v0.20.0 with new Sans-I/O architecture and runtime abstraction.

What's Changing in upcoming v0.20.0+?

The new architecture will address critical issues in v0.17.x:

  • ❌ Callback hell and Arc explosion
  • ❌ Resources leak in callback
  • ❌ Tight Tokio coupling (cannot use async-std, smol, embassy)

v0.20.0+ will provide:

✅ Runtime Independence

  • Support for Tokio, async-std, smol, embassy via Quinn-style runtime abstraction
  • Feature flags: runtime-tokio (default), runtime-async-std, runtime-smol, runtime-embassy

✅ Clean Event Handling

  • Trait-based event handlers with native async fn in trait
  • No more callback Arc cloning or Box::new(move |...| Box::pin(async move { ... }))
  • Centralized state management with &mut self

✅ Sans-I/O Foundation

  • Protocol logic completely separate from I/O (via rtc crate)
  • Deterministic testing without real network I/O
  • Zero-cost abstractions

How to Provide Feedback

We're actively designing v0.20.0+ and welcome your input:

For production use: Stick with v0.17.x branch until v0.20.0+ is stable.
For early adopters: Follow master branch development and provide feedback!

Building and Testing

# Update rtc submodule first
git submodule update --init --recursive

# Build the library
cargo build

# Run tests
cargo test

# Build documentation
cargo doc --open

# Run examples
cargo run --example data-channels

Semantic Versioning

This project follows Semantic Versioning:

  • Patch (0.x.Y): Bug fixes and internal improvements with no public API changes.
  • Minor (0.X.0): Backwards-compatible additions or deprecations to the public API.
  • Major (X.0.0): Breaking changes to the public API.

While the version is 0.x, the minor version acts as the major — i.e., a minor bump may include breaking changes. Once 1.0.0 is released, full semver stability guarantees apply.

Pre-release versions are published with the following suffixes, in order of increasing stability:

  • -alpha.N: Early preview. API is unstable and may change significantly.
  • -beta.N: Feature-complete for the release. API may still have minor changes.
  • -rc.N: Release candidate. No further API changes are expected unless critical issues are found.

For example: 1.0.0-alpha.1 → 1.0.0-beta.1 → 1.0.0-rc.1 → 1.0.0.

Open Source License

Dual licensing under both MIT and Apache-2.0 is the currently accepted standard by the Rust language community and has been used for both the compiler and many public libraries since ( see https://doc.rust-lang.org/1.6.0/complement-project-faq.html#why-dual-mitasl2-license). In order to match the community standards, webrtc-rs is using the dual MIT+Apache-2.0 license.

Contributing

Contributors or Pull Requests are Welcome!!!