Simple one-to-one WebRTC video/voice and data channels
npx @tessl/cli install tessl/npm-simple-peer@9.11.0Simple Peer provides a concise, Node.js-style API for WebRTC that enables simple peer-to-peer connections for video, voice, and data channels. It offers cross-platform compatibility, working in both browser and Node.js environments, with built-in support for duplex streams and advanced WebRTC features like trickle ICE candidates and transceivers.
npm install simple-peerconst Peer = require('simple-peer');ES modules:
import Peer from 'simple-peer';Browser script tag:
<script src="simplepeer.min.js"></script>
<!-- Creates global SimplePeer constructor -->const Peer = require('simple-peer');
// Create peers
const peer1 = new Peer({ initiator: true });
const peer2 = new Peer();
// Handle signaling
peer1.on('signal', data => {
// Send signaling data to peer2 somehow (websocket, etc.)
peer2.signal(data);
});
peer2.on('signal', data => {
// Send signaling data to peer1 somehow
peer1.signal(data);
});
// Handle connection
peer1.on('connect', () => {
peer1.send('Hello from peer1!');
});
peer2.on('data', data => {
console.log('Received:', data.toString());
});
// Don't forget to clean up
peer1.destroy();
peer2.destroy();Simple Peer is built around several key components:
Core WebRTC peer connection functionality with automatic negotiation, signaling, and connection lifecycle management.
class Peer extends Duplex {
constructor(opts?: PeerOptions);
signal(data: SignalData): void;
destroy(err?: Error): void;
}
interface PeerOptions {
initiator?: boolean;
channelConfig?: RTCDataChannelInit;
channelName?: string;
config?: RTCConfiguration;
offerOptions?: RTCOfferOptions;
answerOptions?: RTCAnswerOptions;
sdpTransform?: (sdp: string) => string;
stream?: MediaStream;
streams?: MediaStream[];
trickle?: boolean;
allowHalfTrickle?: boolean;
iceCompleteTimeout?: number;
wrtc?: WebRTCImplementation;
objectMode?: boolean;
allowHalfOpen?: boolean;
}Send and receive text or binary data through WebRTC data channels with automatic buffering and backpressure handling.
// Direct data sending
peer.send(data: string | Buffer | ArrayBufferView | ArrayBuffer | Blob): void;
// Stream interface
peer.write(chunk: any, encoding?: string, callback?: Function): boolean;
peer.read(size?: number): any;Add, remove, and manage audio/video streams with support for track-level operations and dynamic stream modification.
peer.addStream(stream: MediaStream): void;
peer.removeStream(stream: MediaStream): void;
peer.addTrack(track: MediaStreamTrack, stream: MediaStream): void;
peer.removeTrack(track: MediaStreamTrack, stream: MediaStream): void;
peer.replaceTrack(oldTrack: MediaStreamTrack, newTrack: MediaStreamTrack, stream: MediaStream): void;
peer.addTransceiver(kind: string, init?: RTCRtpTransceiverInit): void;Access connection details, statistics, and peer addressing information.
// Connection properties
peer.connected: boolean;
peer.bufferSize: number;
peer.destroyed: boolean;
// Address information
peer.localAddress: string;
peer.localPort: number;
peer.localFamily: string;
peer.remoteAddress: string;
peer.remotePort: number;
peer.remoteFamily: string;
// Methods
peer.address(): AddressInfo;
peer.getStats(callback: (err: Error | null, stats: RTCStats[]) => void): void;// WebRTC support detection
Peer.WEBRTC_SUPPORT: boolean;
// Default configurations
Peer.config: RTCConfiguration;
Peer.channelConfig: RTCDataChannelInit;Simple Peer emits events following the Node.js EventEmitter pattern:
interface SignalData {
type?: 'offer' | 'answer' | 'renegotiate' | 'transceiverRequest' | 'candidate';
sdp?: string;
candidate?: RTCIceCandidateInit;
renegotiate?: boolean;
transceiverRequest?: {
kind: string;
init?: RTCRtpTransceiverInit;
};
}
interface AddressInfo {
address: string;
family: string;
port: number;
}
interface WebRTCImplementation {
RTCPeerConnection: typeof RTCPeerConnection;
RTCSessionDescription: typeof RTCSessionDescription;
RTCIceCandidate: typeof RTCIceCandidate;
}