Simple one-to-one WebRTC video/voice and data channels
—
Core WebRTC peer connection functionality providing automatic negotiation, signaling handling, and connection lifecycle management.
Creates a new WebRTC peer connection with configurable options.
/**
* Create a new WebRTC peer connection
* @param opts - Configuration options for the peer
*/
class Peer extends Duplex {
constructor(opts?: PeerOptions);
}
interface PeerOptions {
/** Set to true if this is the initiating peer */
initiator?: boolean;
/** Custom WebRTC data channel configuration */
channelConfig?: RTCDataChannelInit;
/** Custom WebRTC data channel name */
channelName?: string;
/** Custom WebRTC configuration (ICE servers, etc.) */
config?: RTCConfiguration;
/** Custom offer options for createOffer */
offerOptions?: RTCOfferOptions;
/** Custom answer options for createAnswer */
answerOptions?: RTCAnswerOptions;
/** Function to transform generated SDP signaling data */
sdpTransform?: (sdp: string) => string;
/** MediaStream for video/voice (deprecated, use streams) */
stream?: MediaStream;
/** Array of MediaStreams for video/voice */
streams?: MediaStream[];
/** Enable trickle ICE candidates (default: true) */
trickle?: boolean;
/** Allow half trickle ICE (default: false) */
allowHalfTrickle?: boolean;
/** Timeout for ICE completion in milliseconds (default: 5000) */
iceCompleteTimeout?: number;
/** Custom WebRTC implementation (required in Node.js) */
wrtc?: WebRTCImplementation;
/** Create stream in Object Mode (default: false) */
objectMode?: boolean;
/** Allow half-open duplex streams (default: false) */
allowHalfOpen?: boolean;
}
interface WebRTCImplementation {
RTCPeerConnection: typeof RTCPeerConnection;
RTCSessionDescription: typeof RTCSessionDescription;
RTCIceCandidate: typeof RTCIceCandidate;
}Usage Examples:
const Peer = require('simple-peer');
// Basic peer (browser)
const peer = new Peer({ initiator: true });
// Node.js peer with wrtc
const wrtc = require('wrtc');
const peer = new Peer({
initiator: true,
wrtc: wrtc
});
// Peer with custom configuration
const peer = new Peer({
initiator: false,
config: {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'turn:turnserver.com', username: 'user', credential: 'pass' }
]
},
trickle: false,
iceCompleteTimeout: 10000
});Process signaling data from the remote peer to establish and maintain the connection.
/**
* Process signaling data from remote peer
* @param data - Signaling data (offer/answer/ice candidate)
* @throws {Error} ERR_DESTROYED - if peer is destroyed
* @throws {Error} ERR_SIGNALING - if signaling data is invalid
*/
peer.signal(data: SignalData | string): void;
interface SignalData {
/** Type of signaling message */
type?: 'offer' | 'answer' | 'renegotiate' | 'transceiverRequest' | 'candidate';
/** SDP data for offers/answers */
sdp?: string;
/** ICE candidate data */
candidate?: RTCIceCandidateInit;
/** Renegotiation request flag */
renegotiate?: boolean;
/** Transceiver request data */
transceiverRequest?: {
kind: string;
init?: RTCRtpTransceiverInit;
};
}Usage Examples:
// Handle signaling between peers
peer1.on('signal', data => {
// Send to peer2 via signaling server (websocket, etc.)
signalingServer.send(JSON.stringify(data));
});
signalingServer.on('message', data => {
const signalData = JSON.parse(data);
peer1.signal(signalData);
});
// Direct signaling (same process, for testing)
peer1.on('signal', data => peer2.signal(data));
peer2.on('signal', data => peer1.signal(data));Manage the peer connection lifecycle including negotiation and cleanup.
/**
* Initiate renegotiation of the peer connection
*/
peer.negotiate(): void;
/**
* Destroy and cleanup the peer connection
* @param err - Optional error to emit
*/
peer.destroy(err?: Error): void;Usage Examples:
// Manual renegotiation
peer.negotiate();
// Graceful cleanup
peer.on('close', () => {
console.log('Peer connection closed');
});
peer.destroy();
// Cleanup with error
peer.destroy(new Error('Connection timeout'));Events emitted during the connection lifecycle.
// Connection established and ready
peer.on('connect', () => void);
// Signaling data ready to send
peer.on('signal', (data: SignalData) => void);
// Connection closed
peer.on('close', () => void);
// Fatal error occurred
peer.on('error', (err: Error) => void);
// ICE connection state changed
peer.on('iceStateChange', (iceConnectionState: string, iceGatheringState: string) => void);
// Negotiation completed
peer.on('negotiated', () => void);
// Signaling state changed
peer.on('signalingStateChange', (signalingState: string) => void);
// ICE timeout reached
peer.on('iceTimeout', () => void);Usage Examples:
const peer = new Peer({ initiator: true });
peer.on('signal', data => {
console.log('Send this to remote peer:', JSON.stringify(data));
});
peer.on('connect', () => {
console.log('Peer connected successfully');
peer.send('Hello!');
});
peer.on('iceStateChange', (iceConnectionState, iceGatheringState) => {
console.log('ICE state:', iceConnectionState, iceGatheringState);
});
peer.on('error', err => {
console.error('Peer error:', err.message, err.code);
peer.destroy();
});
peer.on('close', () => {
console.log('Peer connection closed');
});Simple Peer emits errors with specific error codes for different failure scenarios:
interface PeerError extends Error {
code: string;
}Common Error Codes:
ERR_WEBRTC_SUPPORT - No WebRTC support detectedERR_PC_CONSTRUCTOR - RTCPeerConnection constructor failedERR_DESTROYED - Operation on destroyed peerERR_CREATE_OFFER - Failed to create offerERR_CREATE_ANSWER - Failed to create answerERR_SET_LOCAL_DESCRIPTION - Failed to set local descriptionERR_SET_REMOTE_DESCRIPTION - Failed to set remote descriptionERR_ADD_ICE_CANDIDATE - Failed to add ICE candidateERR_ICE_CONNECTION_FAILURE - ICE connection failedERR_CONNECTION_FAILURE - General connection failureERR_SIGNALING - Invalid signaling dataERR_DATA_CHANNEL - Data channel operation failedERR_ADD_TRANSCEIVER - Failed to add transceiverERR_SENDER_REMOVED - Track sender was removedERR_SENDER_ALREADY_ADDED - Track already added to connectionERR_TRACK_NOT_ADDED - Cannot remove track that was never addedERR_REMOVE_TRACK - Failed to remove trackERR_UNSUPPORTED_REPLACETRACK - replaceTrack not supportedUsage Examples:
peer.on('error', err => {
switch (err.code) {
case 'ERR_WEBRTC_SUPPORT':
console.error('WebRTC not supported in this browser');
break;
case 'ERR_ICE_CONNECTION_FAILURE':
console.error('ICE connection failed - check network/firewall');
break;
case 'ERR_SIGNALING':
console.error('Invalid signaling data received');
break;
default:
console.error('Peer error:', err.message);
}
});