werift

September 8, 2026 · View on GitHub

werift

Programmable WebRTC for TypeScript & Node.js

Build media servers, gateways, recorders, bots, test peers, and custom real-time pipelines with a browser-compatible WebRTC API backed by a TypeScript stack you can inspect and extend down to ICE, DTLS, SCTP, RTP/RTCP, SRTP/SRTCP, and DataChannel.

npm version npm downloads license node GitHub stars

Documentation · API Reference · Examples · Interoperability · Roadmap


werift (WebRTC Implementation for TypeScript) is a WebRTC implementation for Node.js written in TypeScript.

Use the browser-compatible RTCPeerConnection API when you want to build quickly, then drop down into ICE, DTLS, SCTP, RTP/RTCP, SRTP/SRTCP, or individual packets when your server-side application needs more control than a browser abstraction provides.

Why werift?

  • Browser-compatible WebRTC API — use familiar RTCPeerConnection, tracks, transceivers, DataChannels, standard events, ICE configuration, and stats in Node.js.
  • TypeScript from PeerConnection down to the protocols — build and debug WebRTC without wrapping a native browser engine or native WebRTC binding.
  • Packet-oriented media control — send and receive RTP directly, making werift a natural fit for SFUs, recorders, relays, gateways, bots, test peers, and custom media pipelines.
  • Modern server connectivity — ICE-Lite, ICE restart, ICE-TCP, and TURN over UDP, TCP, and TLS are implemented in the TypeScript stack.
  • Modular protocol packages — use the full PeerConnection stack or focused ICE, DTLS, SCTP, RTP, and STUN/TURN server packages.
  • Interoperability evidence at multiple levels — Chromium-focused E2E coverage, a Firefox test runner, community-reported Safari interoperability, and independent sipsorcery/webrtc-interop matrices.
  • Inspectable and extensible — instrument RTP/RTCP, experiment with congestion logic, inspect transport state, or modify protocol behavior without crossing a native boundary.

Install

npm install werift

The published werift package currently declares Node.js 22 or newer in its package metadata.

Quick start

The API follows the familiar browser WebRTC model:

import { RTCPeerConnection } from "werift";

const offerer = new RTCPeerConnection();
const answerer = new RTCPeerConnection();

answerer.ondatachannel = ({ channel }) => {
  channel.onmessage = ({ data }) => {
    console.log("answerer received:", data.toString());
    channel.send("hello from answerer");
  };
};

const channel = offerer.createDataChannel("chat");

channel.onopen = () => {
  channel.send("hello from offerer");
};

channel.onmessage = ({ data }) => {
  console.log("offerer received:", data.toString());
};

await offerer.setLocalDescription(await offerer.createOffer());
await answerer.setRemoteDescription(offerer.localDescription!);

await answerer.setLocalDescription(await answerer.createAnswer());
await offerer.setRemoteDescription(answerer.localDescription!);

Here the two peers exchange SDP directly. setLocalDescription() gathers candidates before resolving, so this compact example can exchange the resulting descriptions without a separate trickle-ICE signaling path. Real applications can also use onicecandidate / addIceCandidate() and move signaling to WebSocket, HTTP, SIP infrastructure, a queue, or another transport.

See examples/datachannel for runnable variants.

Browser-compatible WebRTC API

werift exposes a browser-compatible WebRTC API for normal application code, including PeerConnection negotiation, tracks/transceivers, DataChannels, standard events, ICE configuration, and getStats().

A small number of intentional or known edge-case differences remain for backward compatibility or unsupported legacy APIs. They are documented separately in Browser API compatibility, together with the WPT strategy used to track exact browser behavior.

A WebRTC stack that stays programmable

The core media APIs are packet-oriented: MediaStreamTrack can receive and emit RTP, so applications can connect WebRTC directly to an RTP router, recorder, transcoder, media pipeline, or test harness.

werift does not provide operating-system camera/microphone capture as part of the core PeerConnection API. Applications that need browser-style globals and register-backed navigator.mediaDevices.getUserMedia() can opt into werift/polyfill. The guide covers installation, cleanup, media registers, constraints, and TypeScript entrypoints.

flowchart LR
  APP[Your TypeScript application]
  PC[RTCPeerConnection]
  SDP[SDP / negotiation]
  ICE[ICE transport]
  DTLS[DTLS]
  SCTP[SCTP]
  DC[DataChannel]
  SRTP[SRTP / SRTCP]
  RTP[RTP / RTCP]
  MEDIA[Recorder / SFU / gateway / custom media pipeline]

  APP <--> PC
  PC --> SDP
  PC --> ICE
  ICE <--> DTLS
  DTLS <--> SCTP <--> DC
  ICE <--> SRTP <--> RTP <--> MEDIA
  DTLS -. DTLS-SRTP keying .-> SRTP

DTLS and SRTP share the ICE transport, but media is not tunneled through DTLS: DTLS negotiates/exports keys for SRTP, while encrypted RTP/RTCP packets flow over the selected ICE path.

Features

AreaHighlights
Browser APIRTCPeerConnection, tracks/transceivers, DataChannel, standard events, ICE configuration, and browser-compatible negotiation behavior
ICEFull ICE, local ICE-Lite mode, remote ICE-Lite interoperability, trickle ICE, ICE restart, ICE-TCP host candidates
STUN / TURNSTUN plus TURN relay control transports over UDP, TCP, and TLS; turn: / turns: URL handling
SecurityDTLS-SRTP, SRTP, SRTCP, certificate/fingerprint handling
DataChannelSCTP over DTLS, ordered/unordered delivery and partial-reliability controls
RTP / RTCPRFC 3550, SR/RR, PLI, Generic NACK, REMB, Transport-Wide CC
Media resilienceRTX and RED (RFC 2198)
RTP payloadsRTP helpers for VP8, VP9, H.264, AV1, Opus, and RED-related workflows
SimulcastReceive-side simulcast
Bandwidth estimationSender-side estimator driven by Transport-Wide CC feedback
StatisticsBrowser-compatible getStats() report model for RTP, transport, ICE, codec, certificate, DataChannel, and related stats
RecordingNonstandard MediaRecorder / WebM writer paths for Opus, VP8, VP9, H.264, and AV1 tracks
Nonstandard mediaMP4/WebM file playback via mediabunny plus configurable/dummy media-device sources
RTP processingJitter buffer, RED encoder/decoder, DTX, NACK, lip sync, and other packet processors

werift's core strength is WebRTC transport, negotiation, and media-packet control. Device capture, rendering, and general-purpose transcoding remain application concerns; optional nonstandard helpers cover selected server-side media sources and sinks.

What can you build?

SFUs and RTP routers

Receive encoded RTP, inspect or transform it, then forward it to other peers without forcing your application through a browser-style media pipeline.

A separate SFU project built with werift is available at node-sfu.

Recording and media ingestion

Record incoming WebRTC media or connect RTP to your existing storage/transcoding pipeline. See examples/save_to_disk and the nonstandard recorder APIs.

Gateways and protocol bridges

Use WebRTC as one side of a larger system: SIP/media gateways, device bridges, real-time backends, relay services, or application-specific transports.

Automated WebRTC peers

Because the stack runs in Node.js and exposes packet/protocol state, it is useful for integration tests, interoperability suites, synthetic peers, load tests, and protocol debugging.

Protocol experimentation

Use lower layers directly when you need custom ICE, DTLS, SCTP, RTP/RTCP, congestion-control, or packet-processing behavior.

Modular packages

Use the PeerConnection stack or only the protocol layer you need.

PackagePurpose
weriftBrowser-compatible WebRTC API, media transport, DataChannel, and related APIs
werift-iceICE / STUN / TURN client-side transport implementation
werift-dtlsDTLS implementation
werift-sctpSCTP implementation
werift-rtpRTP / RTCP / SRTP / SRTCP and RTP processing utilities
werift-ice-serverRFC 8489 STUN / RFC 8656 TURN server stack and Node reference implementation

The top-level werift package also exports lower-level WebRTC transport and RTP primitives, so applications can mix the browser-compatible API with packet-level control.

Interoperability

Interoperability is validated at more than one level.

Browser interoperability

The repository contains browser E2E tooling and Chromium-focused coverage, including scenarios for ICE-Lite, ICE-TCP, and TURN relay over UDP/TCP/TLS. A Firefox test runner is also included in the E2E workspace.

Safari interoperability is community-verified. Community users have reported using werift extensively with Safari; see Issue #346. Safari is not currently part of the repository's automated browser E2E matrix, so this is presented as community validation rather than a CI guarantee.

Cross-implementation matrix

werift is a participating implementation in sipsorcery/webrtc-interop, which maintains automated Peer Connection and Data Channel Echo tests. Its matrix includes werift alongside implementations such as:

  • aiortc
  • libdatachannel
  • Pion
  • SIPSorcery
  • webrtc-rs

This provides an independent interoperability signal in addition to werift's own E2E tests.

Examples

The examples directory contains runnable examples for high-level WebRTC use cases and lower-level media/protocol work.

ExampleWhat it demonstrates
examples/datachannelDataChannel offer/answer and messaging
examples/mediachannelSending and receiving WebRTC media (installPolyfill + getUserMedia for RTP ingest)
examples/save_to_diskRecording encoded WebRTC media
examples/turn-loopbackHTTPS + TURN/TLS multiplexed loopback and Chromium E2E
examples/interopLocal interoperability peers (installPolyfill for RTP ingest)
examples/untested/getStatsgetStats() example code
examples/untestedRoot examples intentionally excluded from the examples E2E catalog
packages/rtp/src/extra/processorJitter buffering, RED, DTX, NACK, lip sync, and RTP processing utilities

Live demos

MediaChannel

npm run media

Then open:

https://shinyoshiaki.github.io/werift-webrtc/examples/mediachannel/pubsub/answer

Use the browser console and chrome://webrtc-internals/ to inspect the connection.

DataChannel

npm run datachannel

Then open:

https://shinyoshiaki.github.io/werift-webrtc/examples/datachannel/answer

Again, the browser console and chrome://webrtc-internals/ are useful for inspecting signaling, ICE, DTLS, SCTP, and DataChannel behavior.

Debugging

werift uses the debug package throughout the stack.

DEBUG=werift* node your-app.js

For browser interoperability debugging, combine server logs with:

  • chrome://webrtc-internals/
  • SDP offer/answer dumps
  • ICE candidate logs
  • RTP/RTCP packet-level instrumentation

Because the implementation is TypeScript, protocol behavior can be traced directly from application-level events into the relevant transport and packet-processing code.

Documentation

Documentation coverage is still evolving. The examples and source remain useful references for developers working at protocol level.

Repository setup

If you are contributing to werift itself, initialize the pinned upstream Web Platform Tests submodule before running the WPT compatibility tooling:

git submodule update --init --recursive

The repository-level and core protocol package metadata declare Node.js 22 or newer. GitHub Actions validates Node.js 24, which is also required by the opt-in memory-leak harness.

Roadmap

Towards 1.0

The core WebRTC transport, browser-compatible API, and media-packet stack are implemented. Current work towards 1.0 focuses on hardening, test coverage, and developer experience:

  • Expand and improve documentation
  • Increase Web Platform Tests coverage
  • Continue strengthening unit, E2E, interoperability, and long-running reliability tests

Towards 2.0

  • Simulcast send support
  • Additional cipher suites
  • Richer WebRTC statistics coverage

Protocol coverage at a glance

Implemented protocol/features checklist
  • Browser-compatible WebRTC API
  • STUN
  • TURN relay client
    • UDP control transport
    • TCP control transport
    • TLS control transport (turns:)
  • STUN / TURN server package
    • RFC 8489 STUN
    • RFC 8656 TURN
    • Node reference server
  • ICE
    • Full ICE
    • Trickle ICE
    • Local ICE-Lite mode
    • Remote ICE-Lite interoperability
    • ICE restart
    • ICE-TCP host candidates
  • DTLS
    • DTLS-SRTP keying
  • DataChannel / SCTP
  • MediaChannel
    • sendonly
    • recvonly
    • sendrecv
    • multi-track
    • RTX
    • RED
  • RTP
    • RFC 3550
    • VP8 RTP helpers
    • VP9 RTP helpers
    • H.264 RTP helpers
    • AV1 RTP helpers
    • RED (RFC 2198)
  • RTCP
    • SR/RR
    • Picture Loss Indication
    • Receiver Estimated Maximum Bitrate
    • Generic NACK
    • Transport-Wide CC
  • SRTP
  • SRTCP
  • SDP
    • Reuse inactive m-lines
  • PeerConnection
  • Simulcast receive
  • Sender-side bandwidth estimation
  • Browser-compatible getStats() model
  • Nonstandard MediaRecorder workflows
    • Opus
    • VP8
    • H.264
    • VP9
    • AV1
  • Nonstandard media helpers
    • MP4/WebM file playback
    • configurable/dummy media-device sources

References

werift has benefited from the wider WebRTC implementation ecosystem, including:

License

MIT