Node-API addon that embeds Baresip for a simple, session‑centric SIP stack in Node.js and Electron.
- Siperb – Modern softphone (WebRTC + SIP) for Asterisk, FreeSWITCH, and other PBXs.
- Siperb Softphone leverages BareSIP for native UDP/RTP today and will converge with WebRTC for a unified experience.
- Issues / Discussions
- Highlights
- Requirements
- Build (from source)
- Prebuilt binary for distribution
- Install without building (prebuilt branch)
- Quick start
- API
- Examples
- Troubleshooting
- Contributing
Highlights
- Session object with Answer, Hangup, GetStats, SendDTMF
- Clean, mapped event callbacks (no more unknowns)
- Configurable User-Agent, log level, and SIP trace
- Cross-platform audio backend selection (macOS, Windows, Linux)
- Codec control: preload, advertise specific codecs per Register, enumerate available codecs
- Register expires control
Electron (UI) ──IPC──▶ Node child (engine) ──N-API──▶ baresip_node.node ──▶ libre/baresip
▲ │ │
└────────────── events ◀───────┴────────────── RTP/SIP ─┘
- Node 18+ (20/22 recommended)
- CMake 3.20+
- A C/C++ toolchain
- macOS: Xcode Command Line Tools
- Windows: MSVC 2022 Build Tools
- Linux: build-essential
- npm ci
- npm run build
This will produce build/Release/baresip_node.node (the native addon). The JS wrapper is at lib/index.js.
For GitHub consumers who shouldn’t compile locally, we stage the built addon under prebuilt/<platform>-<arch>/node/baresip_node.node and commit it.
- The JS loader in
lib/index.jsloads only fromprebuilt/<platform>-<arch>/node. There is no fallback to a local build.
Note: The prebuilt path is fixed to node and does not vary by Node ABI. If the prebuilt was built with a different Node than your runtime, ensure compatibility or rebuild.
For local development without CI prebuilts, copy build/Release/baresip_node.node to prebuilt/<platform>-<arch>/node/.
If you prefer to consume prebuilts directly from this repo (no local compile), install from the dedicated prebuilt branch. This branch contains the same sources plus committed prebuilts under prebuilt/<platform>-<arch>/node/.
- npm install (one-off):
npm i github:Siperb/baresip-node#prebuilt
- package.json dependency:
{ "dependencies": { "baresip-node": "github:Siperb/baresip-node#prebuilt" } }
Notes
- The
prebuiltbranch is updated by CI and includes only prebuilts;mainremains source-first. - A single Node-API binary per OS/arch is used for both Node and Electron on that platform/arch.
- TLS is disabled by default in the prebuilt to avoid OpenSSL/BoringSSL conflicts in Electron; enable only if you know your environment supports it.
Minimal outbound call flow using registration:
const {
Init, Register, Invite, Shutdown, Callbacks,
SetLogLevel, EnableSipTrace
} = require('baresip-node');
(async () => {
// Observe events (optional)
Callbacks.OnRegisterSuccess = () => console.log('Registered');
Callbacks.OnInviteIncoming = (session) => console.log('Incoming call', session.id);
Callbacks.OnCallConnected = (session) => console.log('Connected', session.callId);
Callbacks.OnCallEnded = (endedSession) => console.log('Ended', endedSession.id);
await Init({
userAgent: 'baresip-node/0.1',
// SIP account
SipUserName: '<user>',
SipAuthUser: '<auth-user>',
SipPassword: '<password>',
SipRegisterServer: '<sip.example.com>',
SipTransport: 'udp',
RegisterExpires: 300,
// Observability
logLevel: 'info',
sipTrace: false,
// Audio backend (defaults shown per platform)
// audio: { srcMod: 'coreaudio', playMod: 'coreaudio' },
// Codec preload and offer control
codecs: { enableAll: false, preload: ['g711', 'g722'] },
AudioCodecs: ['PCMU/8000', 'PCMA/8000']
});
EnableSipTrace(true); // optional at runtime
SetLogLevel('debug'); // optional at runtime
const ok = await Register();
if (!ok) throw new Error('Register failed');
// Place a call to extension 201
const session = await Invite('201', { id: 'my-call-uuid' });
console.log('Invited, callId =', session && session.callId);
})();If you’re developing inside this repository (not consuming via npm), you can require the local entrypoint instead:
const api = require('./lib/index.js');See the Electron example in examples/electron for a full end-to-end UI.
Initializes Baresip, configures logging/audio/codecs, and registers an event bridge. Returns a Promise that resolves to true.
Options (all optional unless noted):
- userAgent: string – SIP User-Agent token for UA
- logLevel: 'none' | 'error' | 'warn' | 'info' | 'debug' – Baresip log level
- sipTrace: boolean – Enable SIP message logging
- logStdout, logTimestamps, logColor: booleans – Console formatting controls
- audio: { srcMod?: string, playMod?: string, srcDev?: string, playDev?: string }
- Platform defaults: macOS coreaudio, Windows winwave, Linux alsa
- codecs: { enableAll?: boolean, preload?: string[] }
- enableAll tries to preload common audio/video codecs
- preload lists module names to preload at startup (e.g., 'g711', 'g722', 'opus')
- SIP account fields bundled for Register convenience:
- SipUserName, SipAuthUser, SipPassword, SipRegisterServer, SipTransport, RegisterExpires
- AudioCodecs, VideoCodecs: array or comma string; if 'all', no restriction is applied
Uses Init-provided account fields to register the UA. Returns Promise.
Codec control at registration time:
- AudioCodecs: string[] | string – e.g., ['PCMU/8000','PCMA/8000']
- VideoCodecs: string[] | string – e.g., ['VP8/90000','H264/90000']
- Special value 'all' removes restrictions so Baresip can offer all enabled codecs.
- If unspecified and enableAll=false, defaults to G.711 PCMU/PCMA.
Expires:
- RegisterExpires or SipRegisterExpires: number (seconds), applied via account_set_regint before ua_register
Places a call to sip:<handle>@<server>. Server is resolved from SipRegisterServer or SipDomain, unless overridden by args.server.
Returns Promise.
Hangs up a call by numeric callId. Returns boolean.
Stops the Baresip main loop and releases the UA.
- SetLogLevel(level)
- EnableSipTrace(enable)
- GetAvailableAudioCodecs(): string[]
- GetAvailableVideoCodecs(): string[]
Represents a call and tracks state and event history.
Fields
- id: string – external app-level id (auto-UUID if not provided)
- callId: number – native Baresip call id
- state: 'new' | 'incoming' | 'outgoing' | 'inviting' | 'progress' | 'ringing' | 'answered' | 'connected' | 'ended'
- direction: 'incoming' | 'outgoing'
- hold: boolean
- mute: boolean
- video: boolean
- localSDP / remoteSDP: string
- Events: Array<{ Activity, Timestamp, Data }>
Methods
- Answer(): boolean
- Hangup(): boolean
- GetStats(): object
- SendDTMF(dtmf: string): void
Assign handlers on Callbacks to observe events. Relevant ones include:
- Registration: OnRegistering, OnRegisterSuccess, OnRegisterFailure, OnUnregistering
- Lifecycle: OnShutdown, OnExit, OnModule, OnCustom
- Calls: OnInviteIncoming(session), OnCallOutgoing(session), OnCallLocalSDP(session), OnCallRemoteSDP(session), OnCallProgress(session), OnCallAnswered(session), OnCallRinging(session), OnCallConnected(session), OnCallEnded(sessionSnapshot), OnCallTransfer(session), OnCallRedirect(session), OnCallTransferFailed(session), OnDTMFReceived(session), OnRTPEstablished(session), OnCallRTCP(session), OnCallMENC(session), OnVUTX(session), OnVURX(session), OnAudioError(event), OnCallHold(session), OnCallResume(session), OnRefer(session), OnSipSessConn(event)
Notes
- OnCallEnded receives a deep-copied snapshot; the live session is removed from
Sessions. - Unknown event payloads are sanitized for readability.
- examples/electron – Standalone Electron app that consumes
github:Siperb/baresip-node#prebuilt
- From repo root:
npm run example:electron
This installs the example’s dependencies and launches Electron. The app spawns a separate Node child process for the SIP engine to avoid Electron/OpenSSL conflicts and uses the platform’s default audio backend (CoreAudio/ALSA/WASAPI). On macOS, grant microphone permission when prompted.
Notes
- The example depends on
github:Siperb/baresip-node#prebuilt, so it behaves like an external consumer and does not use any local build outputs. - TLS is disabled by default; enable only if you control the environment and understand the implications with Electron’s BoringSSL.
- src/baresip_addon.cc – Native addon bridge to Baresip (Node-API)
- lib/index.js – JavaScript wrapper and Session model
- deps/ – vendored dependencies (baresip, libre, openssl, libsrtp, opus)
- build/ – cmake-js build output
- No audio on macOS: Ensure CoreAudio is selected (default). You can set
audio: { srcMod: 'coreaudio', playMod: 'coreaudio' }. - No audio on Linux: Ensure ALSA devices are accessible; set
audio: { srcMod: 'alsa', playMod: 'alsa' }and usesrcDev/playDevif needed. - Codecs not offered: Check
codecs.enableAll,codecs.preload, andAudioCodecs/VideoCodecspassed to Register. - SIP trace:
EnableSipTrace(true)after Init to view SIP messages.
- Dependencies are vendored under
deps/and built via CMake as part of the native target. On macOS, a sample./build_deps_mac.shshows how to build and stage certain libs if you want static linking; it’s optional for most users. - CI publishes prebuilts to the
prebuiltbranch. Themainbranch is source-first.
