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.
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.
- 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-interopmatrices. - Inspectable and extensible — instrument RTP/RTCP, experiment with congestion logic, inspect transport state, or modify protocol behavior without crossing a native boundary.
npm install weriftThe published werift package currently declares Node.js 16 or newer in its package metadata.
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.
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.
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. The optional werift/nonstandard surface adds server-oriented helpers such as MP4/WebM file playback, configurable/dummy media-device sources, RTP utilities, and recording.
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.
| Area | Highlights |
|---|---|
| Browser API | RTCPeerConnection, tracks/transceivers, DataChannel, standard events, ICE configuration, and browser-compatible negotiation behavior |
| ICE | Full ICE, local ICE-Lite mode, remote ICE-Lite interoperability, trickle ICE, ICE restart, ICE-TCP host candidates |
| STUN / TURN | STUN plus TURN relay control transports over UDP, TCP, and TLS; turn: / turns: URL handling |
| Security | DTLS-SRTP, SRTP, SRTCP, certificate/fingerprint handling |
| DataChannel | SCTP over DTLS, ordered/unordered delivery and partial-reliability controls |
| RTP / RTCP | RFC 3550, SR/RR, PLI, Generic NACK, REMB, Transport-Wide CC |
| Media resilience | RTX and RED (RFC 2198) |
| RTP payloads | RTP helpers for VP8, VP9, H.264, AV1, Opus, and RED-related workflows |
| Simulcast | Receive-side simulcast |
| Bandwidth estimation | Sender-side estimator driven by Transport-Wide CC feedback |
| Statistics | Browser-compatible getStats() report model for RTP, transport, ICE, codec, certificate, DataChannel, and related stats |
| Recording | Nonstandard MediaRecorder / WebM writer paths for Opus, VP8, VP9, H.264, and AV1 tracks |
| Nonstandard media | MP4/WebM file playback via mediabunny plus configurable/dummy media-device sources |
| RTP processing | Jitter 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.
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.
Record incoming WebRTC media or connect RTP to your existing storage/transcoding pipeline. See examples/save_to_disk and the nonstandard recorder APIs.
Use WebRTC as one side of a larger system: SIP/media gateways, device bridges, real-time backends, relay services, or application-specific transports.
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.
Use lower layers directly when you need custom ICE, DTLS, SCTP, RTP/RTCP, congestion-control, or packet-processing behavior.
Use the PeerConnection stack or only the protocol layer you need.
| Package | Purpose |
|---|---|
werift |
Browser-compatible WebRTC API, media transport, DataChannel, and related APIs |
werift-ice |
ICE / STUN / TURN client-side transport implementation |
werift-dtls |
DTLS implementation |
werift-sctp |
SCTP implementation |
werift-rtp |
RTP / RTCP / SRTP / SRTCP and RTP processing utilities |
werift-ice-server |
RFC 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 is validated at more than one level.
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.
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.
The examples directory contains runnable examples for high-level WebRTC use cases and lower-level media/protocol work.
| Example | What it demonstrates |
|---|---|
examples/datachannel |
DataChannel offer/answer and messaging |
examples/mediachannel |
Sending and receiving WebRTC media |
examples/save_to_disk |
Recording encoded WebRTC media |
examples/turn-loopback |
HTTPS + TURN/TLS multiplexed loopback and Chromium E2E |
examples/interop |
Interoperability-oriented peers and relay examples |
examples/getStats |
getStats() example code |
packages/rtp/src/extra/processor |
Jitter buffering, RED, DTX, NACK, lip sync, and RTP processing utilities |
npm run mediaThen open:
https://shinyoshiaki.github.io/werift-webrtc/examples/mediachannel/pubsub/answer
Use the browser console and chrome://webrtc-internals/ to inspect the connection.
npm run datachannelThen 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.
werift uses the debug package throughout the stack.
DEBUG=werift* node your-app.jsFor 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 coverage is still evolving. The examples and source remain useful references for developers working at protocol level.
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 --recursiveThe repository-level package metadata declares Node.js 18 or newer. The opt-in memory-leak harness requires Node.js 24 or newer.
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
- Simulcast send support
- Additional cipher suites
- Richer WebRTC statistics coverage
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
werift has benefited from the wider WebRTC implementation ecosystem, including:
MIT