SIP.js WebRTC Library
SIP.js is a comprehensive JavaScript library designed for building real-time communication applications using SIP (Session Initiation Protocol) over WebSockets, with deep integration for WebRTC. It enables peer-to-peer audio and video sessions, instant messaging, presence, and DTMF signaling. The current stable version is 0.21.2. The project maintains an active release cadence with regular minor and patch updates, often introducing new features and addressing bugs. Key differentiators include its TypeScript-first development, compatibility with standard SIP servers like Asterisk and FreeSWITCH, and support for all major web browsers and Node.js environments. It offers both a simplified `SimpleUser` API for common use cases and a full API framework for more granular control over SIP sessions.
Common errors
-
TypeError: require is not a function
cause Attempting to use CommonJS `require()` syntax to import `sip.js` after the library transitioned to ESM-only in v0.21.0.fixUpdate all `require()` statements to ES module `import` syntax, e.g., `import { UserAgent } from 'sip.js';` -
Argument of type 'RegistererOptions' is not assignable to parameter of type 'RegistererRegisterOptions | undefined'.
cause The `register` method of `SimpleUser` changed its signature in v0.21.0, and options are now passed differently.fixPass `RegistererRegisterOptions` via the `registererOptions` property in the `SimpleUser` constructor instead of directly to the `register()` method. -
Property 'hackWssInTransport' does not exist on type 'UserAgentOptions'.
cause Using the `hackWssInTransport` option in `UserAgentOptions` after its removal in v0.18.0.fixRemove `hackWssInTransport` from `UserAgentOptions` and use `contactParams: { transport: "wss" }` instead.
Warnings
- breaking SIP.js v0.21.0 and later are ECMAScript Module (ESM) only. This change impacts projects using custom build processes or CommonJS `require()` syntax.
- breaking The `SimpleUser.register` method signature changed in v0.21.0. It is now `register(registererRegisterOptions?: RegistererRegisterOptions): Promise<void>;`. Any `RegistererOptions` previously passed as the first parameter to `register` must now be provided to the `SimpleUser` constructor.
- breaking In v0.19.0, the Web Session Description Handler (SDH) and `SimpleUser` hold implementation were updated to be RFC 8829 compliant. Users who extended the previous `Web SessionDescriptionHandler` may experience issues.
- breaking The `hackWssInTransport` UserAgent parameter was removed in v0.18.0.
- gotcha In v0.17.0, the Session Description Handler (SDH) was reworked. While not a breaking change for most, users who extended the old default SDH directly will find it in a new location and should copy its functionality into their own source if they wish to continue using it.
Install
-
npm install sip.js -
yarn add sip.js -
pnpm add sip.js
Imports
- Web.SimpleUser
import { SimpleUser } from 'sip.js'; // SimpleUser is nested under Web const SimpleUser = require('sip.js').Web.SimpleUser; // CommonJS is deprecated since v0.21.0import { Web } from 'sip.js'; const simpleUser = new Web.SimpleUser(server, options); - UserAgent
const UserAgent = require('sip.js').UserAgent; // CommonJS is deprecated since v0.21.0import { UserAgent } from 'sip.js'; const userAgent = new UserAgent(options); - SessionState
import { SessionState } from 'sip.js/lib/api/session-state'; // Incorrect deep import path const SessionState = require('sip.js').SessionState; // CommonJS is deprecated since v0.21.0import { SessionState } from 'sip.js'; // ... switch (newState) { case SessionState.Established: ... }
Quickstart
import { Web } from "sip.js";
// Helper function to get an HTML audio element
function getAudioElement(id: string): HTMLAudioElement {
const el = document.getElementById(id);
if (!(el instanceof HTMLAudioElement)) {
throw new Error(`Element "${id}" not found or not an audio element.`);
}
return el;
}
// Options for SimpleUser
const options: Web.SimpleUserOptions = {
aor: "sip:alice@example.com", // caller
media: {
constraints: { audio: true, video: false }, // audio only call
remote: { audio: getAudioElement("remoteAudio") }
}
};
// WebSocket server to connect with
const server = "wss://sip.example.com";
// Construct a SimpleUser instance
const simpleUser = new Web.SimpleUser(server, options);
// Connect to server and place call
simpleUser.connect()
.then(() => simpleUser.call("sip:bob@example.com"))
.catch((error: Error) => {
console.error("Call failed:", error);
// Handle call failure
});