v1.0.2 Stable · 2026-11-03
A from-scratch C++20 WebRTC engine.
12.55 MB. Four platforms. No fork.
NimRTC is an embeddable media engine that keeps the wire-level WebRTC
interop you need (Chrome peers, for both media and DataChannel) and
replaces the 150–250 MB monolith with a layered, plugin-adapted
engine you can grep, swap, and ship on aarch64. Same
source tree ships a P2P client and a relay
gateway (relay profile skips L2 codecs; a from-scratch SFU module is
not a deliverable per the §7 pre-1.0 decision window
closure, BDFL 2026-10-19). DTLS, RTP, audio 3A, and codecs are all
behind header-only plugin interfaces.
- 12.55 MBstatic lib
(vs libwebrtc 150–250 MB) - 4 platformsWindows · Linux x86_64 · macOS arm64 · Linux aarch64
- ~30 K LOCof C++20, end-to-end
(libwebrtc is ~5.5M) - 9 profilescall · transport · relay · agent · agent-gateway · agent-low-latency · relay-agent · teleop · live
See it run
Two in-process NimRTCEngines run a real SDP exchange,
gather ICE host candidates, run STUN connectivity checks on
127.0.0.1, and reach the connected state.
Same engine, same wire, no test mock, no signal server. This is the
examples/loopback-p2p binary, captured below.
The recording above is a synthesized trace of
loopback-p2p's stderr output, generated from
examples/loopback-p2p/loopback-p2p.cpp's
fprintf calls. To re-record a real terminal session with
your own build, run tools/record_loopback_demo.sh (or
.ps1 on Windows) — it captures an asciinema
cast and copies it here.
Quick start
No build needed to evaluate: download the
v1.0.2 prebuilt bundle
(vendored third-party stack — wolfSSL / libsrtp3 / libjuice / msquic —
with .sha256 + .asc + sbom.json).
Linking NimRTC itself still needs a source build for now: the
NIMRTC_INSTALL=ON rules that produce NimRTC's own headers,
static lib and NimRTCConfig.cmake are landed on
main and ship in the next release. Or build the loopback
example locally in ~3 minutes on a 4-core x86_64. All
third-party deps are git submodules, SHA-pinned in
src/third_party/vendor.json.
-
Clone (with submodules)
git clone --recurse-submodules https://github.com/NimRTC/nimrtc.git cd nimrtc -
Configure + build
cmake --preset debug.msvc # or: debug · debug.macos · debug.aarch64 cmake --build build --target loopback-p2p -j -
Run the smoke test
./build/examples/Debug/loopback-p2p # or .exe on WindowsExpected output:[A ice] connectedand[B ice] connectedwithin ~2–3 s, thenexit code: A=1 B=1,returning 0. -
Run the test suite + Chrome interop e2e
ctest --preset tests --output-on-failure python tools/run_e2e_acceptance.py # Chrome ↔ NimRTC Case D
What's working · what's not (be honest)
Shipped in v1.0.2 (Stable)
- Patch release (v1.0.2, 2026-11-03): fixes the WebTransport ALPN mismatch and the oversized Windows bundle, and ships the signing public key with the release. 4-platform bundles + SBOM + detached GPG signatures.
- Chrome ↔ NimRTC DataChannel bidirectional interop (DC-1) over WebTransport / QUIC, PASS E1–E6.
- 9-profile library (
call/transport/relay/agent/agent-gateway/agent-low-latency/relay-agent/teleop/live) with strict JSON↔C++ round-trip tests. - Pre/post-3A PCM tap (race-free
set_pre_process_tap/set_post_process_tap, int16 ASR variant). - PAL Slice 1–8 — plugin-capability resolution, zero runtime overhead, public API unchanged.
- Pluggable DTLS backend (
EngineConfig::dtls_nameresolves to wolfSSL by default, GMSSL opt-in). - Vendored libs: wolfSSL · libsrtp · libopus · libjuice · msquic · WebRTC APM. SHA-pinned.
Deferred to v1.x (and why)
- DataChannel over SCTP-over-DTLS. Chrome is moving DataChannel to WebTransport over QUIC; the
usrsctpsocket class is@deprecatedand still compiles for opt-in callers, but is no longer auto-registered. - iOS / Android native. Roadmap, not a current-track item. No ETA yet.
- Production-grade hardening. API frozen at v1.0.2 per ADR-015 (
NIMRTC_API_VERSION= 10002); SemVer guarantees apply from v1.0.1 (first published stable).
On the roadmap (main, ahead of v1.0.2)
- v1.1 — Quality + packaging + hardening. Reproducible transport-floor benchmarks with CI artifacts;
NIMRTC_INSTALL=ONinstall rules sofind_package(NimRTC)works from an installed tree; WebRTC APM prebuilt shipped alongside;ISctpSocketlifecycle, ICElast_recv_packet()demux, p99 strategy validator, non-standard video clock-rate negotiation, DTLS IPv6set_peer(), NAT-rebindingrehandshake(); Goog-CC BWE, unified adaptive jitter buffer, RTCP feedback loop, engine-level video stats, GMSSL vendoring + SRTP backend seam.
Architecture, in 30 seconds
Four compile-time layers (L0–L3) sit on top of a
Plugin Adaptation Layer (PAL). A profile — also chosen
at build time — decides which layers are even linked into the binary.
The relay profile literally omits L2 codecs from the link.
┌─────────────────────────────────────────────────────────────┐
│ PROFILE — compile-time selection │
│ call │ transport │ relay │ agent │ agent-gateway │ │
│ agent-low-latency │ relay-agent │ teleop │ live │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ L3 Engine │ │ L2 Codecs │ │ L1 Wire / │
│ NimRTCEngine │ ←──→ │ + 3A │ ←──→ │ state │
│ │ │ Opus / H.264 │ │ RTP / ICE / │
│ │ │ VP8 / 3A │ │ DTLS / SRTP │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────────────┐
│ PAL — zero- │
│ overhead resolver │
└──────────────────────┘
│
▼
ITransport · IICETransport · IRTP · ISDP · IJB
IAudio3A · ICodec · IVideoSource/Sink · IDataChannel
Every capability swap (wolfSSL ↔ GMSSL; in-tree 3A ↔ HW 3A;
libjuice ↔ custom ICE) flows through one of these header-only
interfaces. The public NimRTCEngine API does not change.
This page · and what comes next
This page is a placeholder. It hosts a recording of the
in-process loopback-p2p example, not a runnable browser
demo. A real NimRTC-in-your-browser experience (Chrome ↔ NimRTC
audio + video, with getUserMedia on the browser side
and the transport profile compiled to
wasm32-unknown-unknown) has not landed yet and is a
longer-term candidate — it is not on the v1.0–v1.1 roadmap,
which covers quality, packaging, hardening, and the weak-network
chain.
In the meantime, if you want to see NimRTC actually move audio and
video across a real browser peer, the Chrome interop CI
(tools/run_e2e_acceptance.py) is the closest thing we
have to a public-facing demo.