# lynckia/licode: a self-hosted WebRTC communications platform you compile yourself

> Licode is an MIT-licensed C++ media server with a Node.js control layer that lets you run your own WebRTC conference provider. It is aimed at teams willing to build from source and operate the stack, not at anyone looking for a hosted API.

**lynckia/licode** — Open Source Communication Provider based on WebRTC and Cloud technologies

- Repository: https://github.com/lynckia/licode
- Website: http://lynckia.com/licode
- Stars: 3,133 · Forks: 999
- Language: C++
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/lynckia-licode

## What Licode actually is, and the problem it removes

Licode describes itself as an open source WebRTC communications platform. The practical reading of that sentence is narrower than it sounds: Licode is a server you host, not a service you sign up for. It gives you the signalling, room management and media forwarding needed to run multi-party WebRTC sessions, plus two APIs to build on, a client-side API and a server-side API documented at licode.readthedocs.io.

The problem it removes is the integration work of gluing a signalling server, a media server and a room/session model together yourself. WebRTC gives browsers a peer connection API, but not a conference. Someone has to decide which streams are forwarded, who is allowed into a room, and how a client learns about the other participants. Licode ships that layer as a set of cooperating services.

Who it is for follows from that. The README points at two audiences: people who want a quick look and are comfortable with Docker, and people who want to contribute, understand the architecture, or simply do not trust containers. Both paths assume you are willing to run infrastructure. There is no hosted tier mentioned anywhere in the repository.

## How the pieces fit: erizo, nuve and the controller layer

The repository layout is the clearest description of the architecture. The top level contains erizo/, erizoAPI/, erizo_controller/, nuve/, spine/, extras/, scripts/ and test/.

erizo is the C++ media engine, and erizoAPI is the native binding that exposes it to Node.js. erizo_controller is the JavaScript control layer that sits between clients and media workers; inside it, erizo_controller/erizoClient is the browser-facing client library, built by the buildClient script. nuve is the Node.js service that handles the higher-level API surface, and its own installer lives at nuve/installNuve.sh. spine/ appears as a further top-level component in the same tree.

The data flow implied by this arrangement is conventional for a WebRTC SFU-style stack: a browser loads the client library, talks to the controller, and the controller drives native erizo workers that carry the actual media. The important consequence is that the media path is native code and the control path is JavaScript. That split is why the project needs both a C++ toolchain and a Node.js runtime on the same host, and why the Dockerfile installs system dependencies before it installs Erizo.

The test layout confirms the same division of labour. The npm test script runs mocha against nuve/nuveAPI/test/*, erizo_controller/test/erizoController/*, erizo_controller/test/erizoAgent/* and erizo_controller/test/erizoJS/*. There is a separate testRtc script that sets ONLY_FULL_RTC=1 before running the same suites, which suggests the full real-time tests are gated behind an environment variable rather than run by default.

## Installing Licode from source and running the basic example

The README routes source builds to the from_source documentation page, and the Docker path to the docker page. The repository itself shows what those scripts do. The Dockerfile starts from ubuntu:20.04, copies .nvmrc and package.json into /opt/licode/, then copies scripts/installUbuntuDeps.sh, scripts/checkNvm.sh and scripts/libnice-014.patch0 into /opt/licode/scripts/ and runs the dependency installer with two flags.

```dockerfile
FROM ubuntu:20.04
WORKDIR /opt
COPY .nvmrc package.json /opt/licode/
COPY scripts/installUbuntuDeps.sh scripts/checkNvm.sh scripts/libnice-014.patch0 /opt/licode/scripts/
WORKDIR /opt/licode/scripts
RUN ./installUbuntuDeps.sh --cleanup --fast
```

The same Dockerfile then builds the three components in order: Erizo, Nuve, and the basic example. This is the sequence to expect from a source install as well.

```bash
WORKDIR /opt/licode/scripts
RUN ./installErizo.sh -dfEAcs && \
    ./../nuve/installNuve.sh && \
    ./installBasicExample.sh
```

After the native build, the Dockerfile refreshes the linker cache against the dependency build directory, which is a hint that the freshly built libraries are not on the default search path.

```bash
RUN ldconfig /opt/licode/build/libdeps/build/lib
```

Finally, the container entry point is extras/docker/initDockerLicode.sh, and the image records the commit and a timestamp into a RELEASE file. If you install from source rather than Docker, the README points you at the same documentation set for the API you will call afterwards. The basic example installed by installBasicExample.sh is the first thing to run, because it exercises the client library that buildClient produces.

```bash
npm run buildClient
```

That script changes into erizo_controller/erizoClient and invokes the local gulp binary, so the client bundle is a build artefact you generate, not a file you fetch.

## Where Licode is the wrong choice

The most concrete limitation is the platform assumption baked into the build. The Dockerfile pins ubuntu:20.04 and runs installUbuntuDeps.sh, a script whose name says which distribution it targets. Running Licode on a different base image means either reproducing that dependency list yourself or maintaining a fork of the script. The presence of scripts/libnice-014.patch0 in the copied files reinforces how specific the native dependency chain is: a patch file for one library version is checked into the repository.

Second, the release history is thin. The recent releases listed are pre-v11.6 from 2022-09-19, v10 from 2021-05-27 and v9 from 2020-03-09. The last push to the repository was on 2026-09-10, so the codebase is still receiving commits, but the tagged release cadence is far slower than the commit cadence. Anyone who needs a versioned, supported release line should read that gap carefully before adopting.

Third, the default test run is not the real-time test run. npm test executes the mocha suites, while npm run testRtc sets ONLY_FULL_RTC=1 to exercise full RTC behaviour. If your CI runs only npm test, you are not running the same coverage the project uses for end-to-end media checks.

Finally, Licode is the wrong tool if you want a managed service. Nothing in the repository provides signalling, TURN or media relaying as a hosted offering. You supply the hosts, the certificates under cert/, and the operational attention.

## Licode against a plain peer-to-peer WebRTC approach

The obvious alternative is not another media server but no media server at all: build directly on the browser WebRTC API and let peers connect to each other. That works for two-party calls and degrades as participants are added, because every peer must encode and send its stream to every other peer. Licode's erizo media engine exists precisely to sit in the middle and forward streams instead, which is why the repository ships a native C++ component rather than only JavaScript.

The second alternative is a hosted WebRTC platform. The difference is not technical capability but ownership: with a hosted provider you call an API and someone else runs the media servers, whereas Licode asks you to run installErizo.sh and installNuve.sh on your own machines and keep them alive. If your constraint is that media must not leave infrastructure you control, the hosted route is not a substitute. If your constraint is time to first call, it is.

The third alternative is to keep WebRTC peer-to-peer for small rooms and only introduce a forwarding server when room size demands it. Licode does not offer that incremental path as a mode; you either run the platform or you do not.

## Maintenance cost and the MIT licence

The licence is MIT, stated in the README and present as a LICENSE file at the repository root. In practical terms that is a permissive licence with minimal conditions, and it is the reason Licode can be embedded in a commercial product without the copyleft questions a GPL media server would raise. This is a description of what the repository states, not legal advice; if the licence terms matter to your organisation, read the LICENSE file and take your own counsel.

The maintenance cost is dominated by the native build. Every host needs the Ubuntu dependencies installed by installUbuntuDeps.sh, a Node version matching .nvmrc, and a working C++ toolchain for the erizo and erizoAPI components. Upgrades are not a package manager operation. The Dockerfile's sequence of installErizo.sh, installNuve.sh and installBasicExample.sh is the shape of a rebuild, and the ldconfig step against build/libdeps/build/lib has to be repeated whenever those libraries change.

There is also a versioning cost. Because the newest tagged release is pre-v11.6 from 2022, teams that track tags will be pinned to an old line while the master branch moves. The repository does not document a supported-version policy in the available files, so the practical answer is to pin a commit and treat upgrades as a project, not a routine.

## Conclusion

Adopt Licode if you need to own the media path and can commit to running Ubuntu 20.04 build hosts, the erizo C++ media server and the nuve Node.js service as one system. Do not adopt it if you want a managed signalling and TURN service, or if nobody on the team will debug native builds. Before committing, verify that scripts/installErizo.sh completes on your target distribution, that the client bundle builds through npm run buildClient, and that your deployment can satisfy the WebRTC media transport requirements the documentation lists for erizo.

## FAQ

### What is lynckia/licode used for?

It is a self-hosted WebRTC communications platform. You run it to host your own conference provider and build applications on top of its client-side and server-side APIs.

### How do I install lynckia/licode?

The README gives two routes: use the Docker image or build your own, or build Licode from source. Both are documented at licode.readthedocs.io, and the repository's Dockerfile shows the dependency, Erizo and Nuve install steps in order.

### What licence does lynckia/licode use?

The README states the MIT License, and a LICENSE file sits at the repository root.

### Does lynckia/licode ship an official release I can track?

The listed releases are pre-v11.6 from 2022-09-19, v10 from 2021-05-27 and v9 from 2020-03-09. Commits continue, but the tagged release line is much older than the last push.

### Where do I ask questions about lynckia/licode?

The README points to the Licode discourse at discourse.lynckia.com, which it describes as the place where most discussions happen and where answers to Licode problems can be found.

## Sources

- [License: MIT](https://github.com/lynckia/licode/blob/master/LICENSE)
- [lynckia/licode on GitHub](https://github.com/lynckia/licode)
- [Project website](http://lynckia.com/licode)
- [README](https://github.com/lynckia/licode/blob/master/README.md)
- [Releases](https://github.com/lynckia/licode/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lynckia-licode
