baresip: sixteen years of SIP, assembled from selectable modules
Baresip is a modular SIP User-Agent with audio and video support
At a glance
- What is it?
- baresip is a C library for placing SIP calls, and its design shows up in the build system, where you name the modules you want and everything else is left out. That is how a project started in 2010 stays small, and it is also what makes the security choice explicit, because the three key exchange mechanisms it supports are not equivalent and you pick one.
- Who is it for?
- Adopt baresip when you are embedding telephony, testing against a PBX or running a headless agent, and pick your key exchange deliberately, since ZRTP, DTLS-SRTP and SDES give materially different protection and only ZRTP authenticates the far end to a person. Build with a `-DMODULES` list rather than accepting every module, because the audio driver you end up with decides whether the pipeline works on your desktop at all.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A user-agent is a list of modules you choose
The design goals in this README are the summary: a minimalistic and modular VoIP client, standards coverage of SIP, SDP, RTP/RTCP, STUN, TURN and ICE, IPv4 and IPv6, RFC compliance, low footprint, and portable C99 and C11 source.
Modularity is the load-bearing word, and the build system is where you can see it working. This is the entire difference between a full build and a three-module build:
cmake -B build -DMODULES="menu;account;g711"
cmake --build build -jName the modules you need and the rest are not compiled. The README also states the corollary: modules are built when their external dependencies are installed, so a missing system library removes a capability silently rather than failing the build. That is convenient and it is a trap, because a build that lacks the ALSA driver because you did not have the package installed looks exactly like a build that lacks it because you did not ask for it.
The module list itself is worth scanning, because the three-letter names are a compressed index of what a VoIP client actually has to do. `account` loads SIP accounts, `cons` is a UDP or TCP console driver, `ctrl_dbus` and `ctrl_tcp` are two different control interfaces, one speaking DBus and one speaking JSON over TCP. `auresamp` resamples, `auconv` converts sample format, `aufile` uses a WAV file as an audio input, `ausine` generates a sine wave, `augain` adjusts gain, and `aubridge` bridges between audio sources. `avcapture` and `coreaudio` are capture paths for two different Apple platforms, `avcodec`, `avfilter` and `avformat` are the FFmpeg-backed pieces.
That is a well-factored client. It is also a client that makes you responsible for assembly, which is the trade the design goals are making on purpose.
Two more build knobs matter for embedding. There is a static build option, and there is an app-module mechanism that lets a downstream project point the build at its own module directory and its own module list, which is how you add a feature without maintaining a fork.
Four CI workflows, one of which runs Valgrind
The badge row at the top of this README is four separate workflows, and the combination is more informative than it looks for a C project of this age.
There is a build workflow and a lint workflow, which any project should have. Then there is a workflow named for OpenSSL and LibreSSL, which reads as a job that checks the code compiles against both of those libraries and, given the badge title, against an OpenSSL build with deprecated APIs removed. And there is a Valgrind leak check.
That last one is the signal. Running a leak check on every change, in CI, for a media application that allocates audio buffers and network buffers constantly, is real discipline. Memory correctness in C is the failure mode that does not announce itself, and a project that started in 2010 and is still at version 4 in 2026 has had sixteen years to accumulate the kind of leak that only shows up after a week of uptime.
The OpenSSL workflow matters for a different reason, and it is the one that decides whether a long-lived C project is viable at all. The usual way a fifteen-year-old C codebase dies is not a design flaw; it is an upstream library deprecating or removing a function you called. A dedicated job that builds against a library configuration with the deprecated surface taken away turns that from a surprise upgrade failure into a build failure you see before you ship.
So the answer to whether this code still works is not inferred from the release history. It is visible in what the project chose to keep testing. A library that still runs a leak checker and a deprecated-API build in 2026 is being maintained, not merely still compiling.
The project also carries a CHANGELOG, a `.clangd` configuration for the language server, and a `packaging/` directory, and it accepts patches through GitHub pull requests or its own Google Group mailing list.
Three key exchange mechanisms, and they are not equal
SIP media encryption is where choosing a client becomes a security decision, and this README lists the options without pretending they are interchangeable.
Signalling is encrypted with TLS, and audio and video with Secure RTP. On top of that sit three different ways to agree the keys. DTLS-SRTP performs the key exchange over a datagram transport, which is the mechanism WebRTC standardised and which is why there is a `webrtc/` directory in the tree. ZRTP performs an end-to-end key exchange using a passphrase-derived secret and authenticates the humans at both ends, telling them a short authentication string to compare verbally. SDES carries the key inside the session description, in band, which means anyone who can see the signalling can see the key.
Those are three materially different security properties, and the ordering is not close. ZRTP is the only one of the three that gives the two people on a call evidence about who is on the other end, because it shows them a word they can read out loud. DTLS-SRTP protects the media against an attacker on the path and against passive recording, but it authenticates the transport rather than the person. SDES is a convenience that assumes your signalling is already trustworthy, which is a reasonable assumption inside a TLS tunnel to your own server and a poor one across an untrusted one.
The design goal of RFC compliance is what produces this menu rather than a single choice, and it is the right goal for a library whose job is to interoperate with whatever is on the other end. But it means the security decision is yours, made once, in configuration, and it is the one decision on this list that you should be able to explain to somebody else.
One related detail worth knowing: the call feature list includes call recording, which is a legitimate feature and also a significant capability to have enabled on a device that holds real credentials.
Who routes the call: STUN, TURN, ICE, NATPMP and PCP
A SIP client that only works on an open network is not a client, and this project's answer is a whole section of protocols, one of which involves trusting a third party.
STUN discovers your public address so a peer can reach you. TURN relays the media through a server when a direct path will not form, and a relay sees the traffic in transit, so using one is a decision to route your calls through somebody else's infrastructure. ICE is the negotiation mechanism WebRTC standardised for choosing between the candidates that STUN and TURN produce, and its presence here is the same signal as the DTLS-SRTP module: this client speaks the WebRTC transport stack alongside SIP signalling.
NATPMP and PCP are the automatic port-mapping protocols. They ask your own router to open a port for you rather than making you configure it. That is convenient and it is a trust decision, because it means the client is asking a device on your network to punch a hole in its firewall on its behalf, and the mechanism has been the subject of abuse in the wild for that reason.
The signalling list adds SIP outbound for NAT traversal, which is a different answer again: rather than negotiating around the network, the client signals through a designated outbound proxy that other clients can reach.
What makes this list a design decision rather than a feature list is the trust gradient running through it. STUN and ICE with a direct path keep everything local. TURN moves your media to a relay operator. NATPMP and PCP ask your router for help. SIP outbound delegates path establishment to your server operator. All five ship here, and the README does not choose for you.
The networking section also lists multihoming with IPv4 and IPv6 and automatic network roaming, which is the last piece: a laptop that moves between a wired office network and a phone hotspot has to re-resolve and re-anchor, and doing that without dropping the call is a feature you only appreciate when it works.
Building it, and the config directory that appears by itself
Two packages have to be present before anything else: libre, which is this project's own media library in a separate repository, and OpenSSL.
A debug build with installation is three commands:
cmake -B build
cmake --build build -j
cmake --install buildA release build drops the install step, which is easy to miss and matters if you are scripting a build:
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -jNote the difference in outcome. The debug sequence installs the binaries and their configuration; the release sequence leaves you with a binary in the build tree that you place yourself. If you are building for deployment rather than experimenting, that is the line to get wrong.
Two more variations worth knowing exist. For an embedder who cannot ship shared libraries, there is a static build, and for a toolchain that is not the default compiler, there are flags to select clang and clang++ explicitly. And for downstream development, the app-module mechanism points the build at another directory of modules:
cmake -B build -DAPP_MODULES_DIR=../baresip-apps/modules -DAPP_MODULES="auloop;vidloop"
cmake --build build -jThat last one is the extension story for projects that keep their own fork of the module set, and it is the difference between maintaining a fork and maintaining a patch.
Running it is one command, and the first run has a side effect worth anticipating:
build/baresipConfiguration files in `$HOME/.baresip` are generated automatically the first time you run the client. So a fresh install is self-configuring, which is convenient for a first run and means you have to look at what it wrote before you trust it in a configuration that matters. The wiki has the configuration reference, and configuration examples live in the repository under `docs/examples`.
For the API, documentation is generated with Doxygen from a config file in `mk/`, and the output directory is configurable there.
Eight audio drivers decide whether the pipeline runs at all
The driver lists are long, and they are the real portability story of this project, because a media client either acquires the audio device or it is a library that does nothing.
Audio drivers: ALSA on Linux, PulseAudio on POSIX systems, Android through AAudio and OpenSLES, GStreamer's playbin as an input source, JACK, CoreAudio and AudioUnit on macOS and iOS, PortAudio as a portable fallback, and WASAPI on Windows.
Video sources and outputs: capture on iOS through avcapture, FFmpeg's libavformat and avdevice, DirectShow on Windows, AVCapture on macOS, V4L and V4L2 on Linux, and an X11 grabber; output through SDL2 and through X11.
Read that as a build matrix rather than a feature list. Each driver pulls in a system dependency, and the module you select is what determines whether that dependency matters. A build with `MODULES` set to a three-element list has no drivers at all unless you named them, which loops back to the earlier point about silent omissions.
The audio pipeline features are what separate a call that works from one that does not, and they are the part of the list most worth reading. There is a low-latency pipeline, audio filter plugins, packet loss concealment for when the network drops packets, automatic gain control and noise reduction, acoustic echo control, an internal resampler for fixed sampling rates, a configurable ringtone playback device, and configurable sample formats including signed 16-bit, 24-bit and float.
The resampler deserves a note. It exists for fixed sampling rates, which is the classic problem of a codec that insists on 8 kHz or 16 kHz meeting a sound card that wants 48 kHz. Resampling on every call would be a latency and quality problem, so the internal resampler is there to be configured once.
The codec lists are broad enough that interoperability is rarely the constraint: AAC, aptX, AMR narrowband and wideband, Codec2, G.711, G.722, L16 and Opus for audio, and H.264, H.265, VP8, VP9 and AV1 for video, with configurable resolution, frame rate, bitrate and pixel format and hardware acceleration paths for both encode and decode.
Against a WebRTC-first stack, and against not building a softphone
The alternative to this library is usually one of two other projects, and the comparison is about architecture rather than features.
The first is a WebRTC-first stack. The difference is that WebRTC was designed for browsers talking to browsers: media negotiation, congestion control and NAT traversal are in the core protocol, while SIP was designed for signalling and inherits its media layer from a different era. For a call between two browser tabs, WebRTC is the better answer by a wide margin. For a call into a corporate PBX, a carrier or a VoIP trunk, it is not a question at all, because those endpoints speak SIP. Barefip's own architecture is the interesting part: it carries the WebRTC transport pieces, DTLS-SRTP, ICE, STUN and TURN, next to the SIP stack, which tells you that the project's position is that the two worlds need to meet and somebody has to carry the bridge.
The second alternative is not building a client at all, and using a hosted softphone or letting a PBX terminate the media. Then the transport, the codecs, the echo cancellation and the NAT traversal are somebody else's problem. What you lose is the SIP identity in your own infrastructure and any control over where the media goes.
Then the question of whether a user-agent is what you want. The management surfaces listed here are an embedded web server with an HTTP interface, a command-line console over UDP or TCP, a command-line interface, simple configuration files and an MQTT module. There is no graphical interface in this repository. So if you want a desktop softphone with a contact list and a call history, this is the library underneath one rather than the application itself.
Where it does fit is embedding: a PBX integration, a headless test harness driving real SIP, an agent placing calls from a queue, or a device with a display and no desktop. The call feature list supports that shape, with unlimited SIP accounts, unlimited calls, unattended call transfer, auto answer, conferencing, presence in the address book and message waiting indication, which are server-side capabilities rather than desktop ones.
And the licence is three-clause BSD, so embedding it in a product you ship is not a licensing problem.
Sixteen years, monthly releases, and a C dependency you own
The copyright line runs from 2010 to 2026, which is the honest headline for a library like this. Sixteen years in a protocol that businesses still buy and nobody has an incentive to replace.
The release history supports the reading that it is still moving. Three minor versions arrived in quick succession: v4.9.0 on 2026-06-17, v4.10.0 on 2026-07-22 and v4.11.0 on 2026-08-25. Roughly monthly, on a four-major stable series, with the last push on 2026-09-18. For a project whose competitors are mostly abandoned forks, that is the relevant comparison.
The upgrade cost is the C reality. Baresip is a C library with a module ABI, so you pin a version, you rebuild against it, and you test the media path after every upgrade rather than after every major one. The two upstream dependencies make that concrete: libre is this project's own library on a separate release cadence, and OpenSSL is the one that moves underneath you. That is what the dedicated OpenSSL and LibreSSL workflow is defending against, and it is why the wiki offers separate guides for installing a stable release and installing the git version.
The codebase is C99 and C11, and the tooling reflects a modern setup rather than an old one: CMake as the build system, a `.clangd` configuration so an editor can navigate it, a lint workflow, and Doxygen documentation generated from `mk/`.
One practical warning for anyone planning to run this in production. This is a client that will hold live SIP credentials and place real calls, and the four CI workflows tell you the maintainers verify memory correctness and library compatibility. Neither of those is the same thing as a security review of a SIP stack, so put it behind the same controls you would put any credential-holding network client, and pin the version.
Editorial conclusion
Adopt baresip when you are embedding telephony, testing against a PBX or running a headless agent, and pick your key exchange deliberately, since ZRTP, DTLS-SRTP and SDES give materially different protection and only ZRTP authenticates the far end to a person. Build with a `-DMODULES` list rather than accepting every module, because the audio driver you end up with decides whether the pipeline works on your desktop at all. Do not reach for it as a desktop softphone, since the management surface is a CLI, a UDP console, an embedded web server and MQTT, and remember that it holds live SIP credentials, so a clean Valgrind run is not the same as a hardened deployment.
Frequently asked questions
What is baresip and who is it for?
baresip is a portable and modular SIP user-agent with audio and video support, written in C99 and C11 and distributed under the three-clause BSD licence. The design goals describe a minimalistic, modular VoIP client, so it suits people embedding telephony, testing against a PBX or running a headless agent rather than people looking for a desktop softphone.
How do I build baresip with only the modules I need?
Pass a semicolon-separated list to CMake, for example `cmake -B build -DMODULES="menu;account;g711"` followed by `cmake --build build -j`. Modules are only built when their external dependencies are installed, so a missing system package removes a module silently rather than failing the build.
Which encryption options does baresip support for calls?
Signalling over TLS and media over Secure RTP, with three key exchange mechanisms: DTLS-SRTP, which is the datagram-based exchange WebRTC standardised, ZRTP, which authenticates the humans at both ends with a short authentication string, and SDES, which carries the key inside the session description in band.
How does baresip get through NAT?
It supports STUN for address discovery, TURN for relaying media when a direct path will not form, ICE for choosing between candidates, NATPMP and PCP for automatic port mapping on your own router, and SIP outbound for delegating path establishment through a designated proxy.
What audio and video drivers does baresip support?
Audio drivers include ALSA, PulseAudio, Android AAudio and OpenSLES, GStreamer, JACK, CoreAudio and AudioUnit, PortAudio and Windows WASAPI. Video sources include iOS avcapture, FFmpeg libav, DirectShow, macOS AVCapture, V4L/V4L2 and an X11 grabber, with SDL2 and X11 for output. The drivers you select determine which system dependencies the build needs.
Where does baresip store its configuration?
In `$HOME/.baresip`, and those files are generated automatically the first time you run the client, so a fresh install configures itself. Configuration examples live in the repository under docs/examples, and the reference documentation is in the project wiki.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/baresip-baresip)