
Licode WebRTC is an open-source, MCU-based WebRTC communications platform that lets developers build real-time video conferencing applications without relying on commercial SDKs. It uses Erizo client and server APIs to manage rooms, streams, and participant events over a centralized media server. Developers typically deploy Licode via Docker for rapid prototyping or build from source for production customization, and it remains a popular choice for teams that need full control over their WebRTC infrastructure. For managed alternatives, VideoSDK offers hosted RTC APIs with Prebuilt UI and multi-platform SDKs that eliminate infrastructure overhead entirely. Explore VideoSDK's video calling documentation for a comparison of managed vs self-hosted approaches. Open-source WebRTC platforms have gained significant traction among developers who want transparency, customization, and freedom from vendor lock-in. Licode stands out as one of the earlier MCU-based solutions, built in C++ with a JavaScript client layer, and it continues to attract teams building multi-party video applications. Whether you are evaluating Licode for a prototype or planning a production deployment, this guide walks you through its architecture, client API components, setup process, advanced features, browser compatibility challenges, and scaling strategies. We also compare Licode against other open-source alternatives like Jitsi, Janus, and LiveKit so you can make an informed infrastructure decision. ## What Is Licode WebRTC? Licode WebRTC is defined as an open-source WebRTC platform that implements a Multipoint Control Unit (MCU) architecture to route and mix media streams between participants in real-time video sessions. Unlike peer-to-peer WebRTC topologies where every participant maintains a direct connection to every other participant, Licode centralizes media processing on a server. Each participant sends one stream to the MCU and receives one mixed stream back, which dramatically reduces client-side bandwidth and CPU usage for larger rooms. Licode works by exposing two primary layers: the server-side Erizo controller, written in C++ and Node.js, and the client-side Erizo JavaScript API that runs in the browser. The server manages room creation, stream mixing, token-based authentication, and media routing. The client API handles stream creation, room connections, and event subscriptions. Core concepts include rooms (virtual spaces where participants exchange media), streams (audio/video/data tracks published by participants), and the Erizo classes that bind these concepts together. Licode is released under the MIT license, making it commercially usable without licensing fees. At a high level, the Licode architecture works as follows. A browser client running the Erizo JavaScript API sends WebRTC media and signaling traffic to the Licode signaling server. The signaling server manages room and stream state and communicates with the Licode MCU core, which is written in C++. The MCU core performs media mixing and routing, sending composite streams back to the client. Alongside this, TURN and STUN servers handle NAT traversal for both the client and the MCU server. A separate Node.js token server issues JWT authentication tokens to the signaling server to validate participant access. This architecture centralizes media processing, which simplifies client implementation but introduces a single point of infrastructure that must be scaled and monitored. For developers who prefer a serverless approach, VideoSDK's video calling API handles room management, media routing, and scaling without any server infrastructure to maintain. ## Core Components of the Licode Client API The Licode client API revolves around three primary Erizo classes that together manage the full lifecycle of a WebRTC session. Understanding how these classes interact is essential for building reliable multi-party video applications. ### Erizo.Stream Erizo.Stream is the foundational class for creating and managing media tracks in a Licode session. Developers create a stream by specifying media constraints, such as whether audio is enabled, whether video is enabled, the desired video resolution, and the frame rate. The stream object encapsulates the local camera and microphone input or a screen-share capture from the browser. For screen sharing, Licode leverages the browser's media device display API to capture the user's screen, window, or browser tab. The stream class also supports data-only streams that carry no audio or video, which are useful for real-time text chat or signaling between participants without opening a separate WebSocket connection. Once created, a stream must be published to a room for other participants to subscribe to it. ### Erizo.Room Erizo.Room manages the lifecycle of a participant's connection to a Licode room. The room class handles the join and leave operations, stream publication, stream subscription, and participant discovery. When a client joins a room using a valid token, the room object emits events that notify the client of existing participants, their published streams, and any state changes. The room also manages the unsubscribe operation when a participant leaves or stops publishing. Developers use the room API to control who receives which streams, enabling selective subscription patterns where a client subscribes only to the active speaker rather than all participants simultaneously. ### Erizo.Events Erizo.Events provides the event-driven layer that ties streams and rooms together. Events fire when a stream is added to a room, when a participant connects or disconnects, when a data channel message arrives, and when errors occur during ICE negotiation or media transmission. Developers register callback handlers on room and stream objects to respond to these events in real time. Common event patterns include updating the UI when a new participant joins, rendering a remote video element when a stream is subscribed, and triggering reconnection logic when a network interruption causes a stream to drop. The interaction among these three components follows a predictable session lifecycle. First, the developer creates an Erizo.Stream with the desired media constraints. Next, a token is generated on the server side. The client then creates an Erizo.Room instance and connects using that token. Once connected, the local stream is published to the room. The client listens for stream-added events from Erizo.Events and subscribes to each remote stream that appears. Participant join and leave events are handled to update the UI accordingly. Finally, when the session ends, the room is disconnected and all resources are cleaned up. This lifecycle pattern, stream creation followed by room connection followed by event-driven subscription, is the backbone of every Licode application. ## Setting Up Licode for Development Setting up Licode for development involves choosing between a Docker-based quick start and a source build, then configuring TURN/STUN servers for reliable NAT traversal. Each approach has tradeoffs depending on whether you need rapid prototyping or deep customization. ### Docker Quick-Start The fastest way to get Licode running is through the official Docker image. Docker encapsulates all dependencies, including the C++ Erizo core, Node.js nuve layer, and the MongoDB instance that Licode uses for room metadata. Developers pull the official Licode image from Docker Hub, expose the required ports for signaling and media traffic, and launch the container. The default configuration includes a basic room service and a sample client application that demonstrates stream publishing and subscribing. Port configuration is critical: the signaling server typically runs on port 3004, the room service on port 3001, and the Erizo MCU uses a range of UDP ports for media traffic. Developers must ensure that all these ports are accessible, especially when testing across different networks. For local development, running the container with host networking simplifies port management, though production deployments require more granular network configuration. ### Building from Source Building Licode from source gives developers full control over compilation flags, custom media processing modules, and server-side extensions. The build process requires a Linux environment with C++ build tools, Node.js, Python, and several media processing libraries including libnice, openssl, and codecs like H.264 and VP8. The C++ core, known as Erizo, must be compiled first, followed by the Node.js layers (nuve and erizoController) that provide the REST API and signaling. This approach is more time-consuming and error-prone than Docker, particularly because dependency version mismatches can cause build failures. However, it is the only way to add custom C++ media processing or modify the MCU mixing logic. Developers who need to integrate custom video analysis, recording pipelines, or specialized codecs will need this level of access. ### Configuring TURN/STUN TURN and STUN servers are essential for WebRTC connectivity when participants are behind NAT routers or firewalls. STUN servers help clients discover their public IP addresses, while TURN servers relay media traffic when direct peer connections fail. Licode reads TURN and STUN configuration from its server-side configuration files, and these settings are passed to clients during the room connection handshake. Without properly configured TURN servers, participants on restrictive networks (corporate firewalls, mobile carriers) will fail to establish media connections. Free public STUN servers work for development, but production deployments require dedicated TURN infrastructure. Services like coturn can be self-hosted, or developers can use managed TURN providers. In a typical Licode network topology, a client behind NAT first contacts a STUN server to discover its public IP address. If peer-to-peer connectivity fails, the client falls back to a TURN server, which relays media traffic on its behalf. The client also sends WebRTC media directly to the Licode MCU server, which mixes the streams and sends a composite stream back. The Licode signaling server handles room and token management for the client and controls the MCU server. ## Creating a Multi-Party Video Call Building a multi-party video call with Licode involves three critical phases: server-side token generation, client-side room connection with stream publishing, and bandwidth management for participants on varying network conditions. ### Token Generation Licode uses token-based authentication to control access to rooms. Tokens are JSON Web Tokens generated server-side using the room ID, participant role, and a shared secret configured in the nuve layer. The server-side application calls the Licode REST API to create a room, then generates a token for each participant who is authorized to join. Security considerations include keeping the shared secret on the server only, setting token expiration times to limit replay attacks, and using role-based tokens to distinguish between publishers (who can send media) and subscribers (who can only receive). Never expose the nuve API key or secret to the client. For a managed alternative that handles token generation automatically, VideoSDK's authentication guide explains how hosted RTC platforms abstract this step entirely. ### Joining a Room Once the client receives a token, it creates an Erizo.Room instance and calls the connect method with the token string. After the connection succeeds, the client creates an Erizo.Stream with the desired media constraints (audio enabled, video enabled, resolution, frame rate) and publishes it to the room. The room then emits stream-added events for every existing participant's stream, and the client subscribes to each one to render the remote video. The subscription model in Licode is flexible: clients can subscribe to all streams, only audio, only video, or specific resolutions. This flexibility is important for multi-party calls where rendering six or more simultaneous video feeds can overwhelm a mobile device's GPU. A common pattern is to subscribe to high-resolution video for the active speaker and low-resolution or audio-only for other participants. ### Managing Bandwidth Bandwidth management is one of the most challenging aspects of multi-party WebRTC. Licode provides several mechanisms to adapt to varying network conditions. The videoSize constraint in Erizo.Stream lets developers specify maximum width and height, which the MCU respects when mixing streams. Developers can also adjust the bitrate of published streams dynamically based on detected network quality. For low-bandwidth scenarios, the recommended approach is to reduce video resolution, lower the frame rate, or disable video entirely and fall back to audio-only. Licode's MCU architecture helps here because each client only sends one stream to the server, regardless of the number of participants. The server handles the mixing and sends back a single composite stream, which keeps client upload bandwidth constant even as the room grows. However, the server's bandwidth and CPU requirements scale with the number of participants and streams, which is the primary tradeoff of MCU vs SFU architectures. In the participant flow, each browser publishes its local stream to the Licode MCU. The MCU mixes all incoming streams into a single composite stream and sends that mixed stream back to each participant. Whether there are three participants or ten, each browser only receives one mixed stream, which keeps the client-side rendering logic simple and bandwidth predictable. ## Advanced Features You Can Unlock Licode supports several advanced capabilities beyond basic audio and video conferencing that make it suitable for richer real-time applications. ### Data Channels Licode supports WebRTC data channels through Erizo data streams. Data channels allow participants to send arbitrary text or binary data over the same WebRTC connection that carries media, without opening a separate WebSocket. Common use cases include real-time chat overlays, collaborative whiteboards, shared state synchronization, and custom signaling between participants. Data channel streams in Licode are created similarly to media streams but with audio and video disabled. Once published to a room, other participants subscribe to the data stream and receive messages through event callbacks. ### Screen Sharing Screen sharing in Licode uses the browser's display media API to capture the user's screen, application window, or browser tab. The captured stream is then published as an Erizo.Stream with screen sharing enabled. Browser support for screen capture varies: Chrome and Firefox have supported it for several years, while Safari added support more recently. Developers should feature-detect the display media API before offering screen share as an option, and provide clear user prompts since browsers require explicit permission for screen capture. ### External Media Ingestion Licode can ingest external media sources that are not produced by a browser participant. This includes RTSP streams from IP cameras, file-based media, and other WebRTC streams from external sources. The server-side API allows developers to create external streams that are published to a room like any participant stream. This is useful for surveillance applications, live event broadcasting where a professional encoder feeds an RTSP stream, or integrating pre-recorded content into a live session. ### Recording and Playback Licode provides server-side recording capabilities that capture the mixed stream or individual participant streams to disk. Recordings are stored as media files that can be played back later or processed by external transcription and analytics pipelines. Developers configure recording through the server API, specifying which streams to record and the output format. For applications that need post-call analytics, VideoSDK's recording and transcription features offer built-in cloud recording with automatic transcription as a managed alternative. ## Browser Compatibility and Common Pitfalls Browser compatibility remains one of the most persistent challenges in WebRTC development, and Licode applications are no exception. Each major browser has quirks that developers must address. ### Safari Support Safari has historically been the most challenging browser for WebRTC. Its H.264-only video codec support means that VP8 or VP9 streams from Chrome or Firefox participants may not render correctly without transcoding on the server side. Licode's MCU can handle transcoding, but it adds CPU overhead. The widely recommended adapter.js library normalizes WebRTC API differences across browsers and is essential for any Licode deployment that targets Safari users. Developers should also test Safari on both macOS and iOS, as the iOS version has additional restrictions on autoplay policies that require user interaction before video can play. ### Chrome and Firefox Quirks Chrome and Firefox generally have the most complete WebRTC implementations, but differences remain in ICE candidate handling and SDP negotiation. Chrome tends to gather ICE candidates more aggressively, while Firefox may wait longer before triggering the ICE connection. This can cause delays in connection establishment if the application expects immediate candidate delivery. SDP differences, particularly around codec preferences and media direction attributes, can cause one-way audio or video issues. Testing across both browsers during development is essential. ### Debugging Tips Effective debugging of Licode WebRTC applications requires monitoring several layers. Browser console warnings often reveal permission denials, codec mismatches, or deprecated API usage. The Licode server logs provide visibility into room creation, token validation, and stream lifecycle events. For TURN-related issues, checking the TURN server logs for allocation requests and relayed traffic helps identify NAT traversal failures. Implementing reconnection logic on the client side is critical for production applications. When a network interruption causes a stream to drop, the client should attempt to republish the stream after a brief delay, and the UI should indicate the reconnection state to the user. ## Scaling Licode for Production Scaling Licode from a single-server development setup to a production deployment requires horizontal scaling, monitoring, and security hardening. ### Horizontal Scaling with Multiple MCU Nodes Licode supports horizontal scaling by distributing rooms across multiple MCU nodes. The nuve layer acts as a load balancer, assigning new rooms to available Erizo instances based on capacity. This requires a shared MongoDB instance for room metadata and a mechanism for the signaling layer to route participants to the correct MCU node. Scaling challenges include managing cross-node participant communication (participants in rooms on different MCU nodes need their streams routed between nodes), handling node failures gracefully, and balancing load based on actual media processing requirements rather than just room count. ### Monitoring and Metrics Production Licode deployments need comprehensive monitoring. The server exposes metrics that can be scraped by Prometheus or similar monitoring systems. Key metrics to track include the number of active rooms, participants per room, CPU usage per MCU node, bandwidth consumption, and ICE connection success rates. Custom logging that correlates client-side events with server-side room state helps diagnose issues that span the client-server boundary. Setting up alerts for high CPU usage, failed token validations, and TURN relay traffic spikes helps catch problems before they affect users. ### Security Hardening Security hardening for Licode includes enabling encryption for all signaling and media traffic, implementing role-based access control through token scopes, and protecting the nuve REST API behind a firewall or reverse proxy. End-to-end encryption (E2EE) is not natively supported by Licode's MCU architecture because the server needs access to unencrypted media for mixing. For applications that require E2EE, an SFU architecture or a managed platform like VideoSDK that supports E2EE may be more appropriate. ## How Licode Compares to Other Open-Source MCU Solutions Developers evaluating Licode often compare it against Jitsi, Janus, and LiveKit. Each platform has distinct strengths. | Platform | Architecture | Language Stack | License | Community Activity | Best For | | --- | --- | --- | --- | --- | --- | | Licode | MCU | C++ / Node.js / JS | MIT | Moderate | Custom MCU mixing, research projects | | Jitsi | SFU | Java / JS | Apache 2.0 | Very active | Large-scale video conferencing, drop-in solutions | | Janus | SFU / MCU hybrid | C | GPL3 | Active | Modular plugins, IoT, streaming | | LiveKit | SFU | Go / TypeScript | Apache 2.0 | Very active | Modern SFU, mobile-first apps, managed option | Licode's MCU architecture makes it unique among these options. Most modern platforms have moved to SFU architectures, which scale better for large participant counts because they forward streams without mixing. Licode's MCU approach simplifies client-side rendering (one incoming stream) but shifts the computational burden to the server. For developers who want the simplicity of a managed solution without infrastructure overhead, VideoSDK's Prebuilt UI Kit offers zero-code embedding with sub-300ms latency across 10+ platform SDKs. [LINKABLE ASSET: comparison table] ## Definitions Glossary > Licode: An open-source WebRTC platform that uses an MCU architecture to mix and route media streams between participants in real-time video sessions, released under the MIT license. > Erizo.Stream: The Licode client-side class that represents a media or data stream, created with specific constraints for audio, video, screen sharing, or data channel communication. > Erizo.Room: The Licode client-side class that manages a participant's connection to a virtual room, handling join, leave, publish, and subscribe operations. > MCU (Multipoint Control Unit): A media server architecture where each participant sends one stream to the server and receives one mixed stream back, reducing client bandwidth at the cost of server-side processing. > TURN/STUN: Network protocols that enable WebRTC connectivity across NAT boundaries. STUN helps clients discover public IP addresses, and TURN relays media when direct connections fail. > Nuve: The Licode server-side REST API layer that handles room creation, token generation, and service management, backed by MongoDB. ## Key Takeaways - Licode WebRTC provides an open-source MCU architecture that simplifies client-side rendering by mixing all participant streams server-side, making it suitable for applications where client bandwidth and CPU are constrained. - The Erizo client API (Stream, Room, Events) forms the core development surface, and understanding the stream-to-room-to-event lifecycle is essential for building reliable Licode applications. - Docker deployment offers the fastest path to a working Licode instance, while building from source is necessary for custom media processing or C++ level modifications. - Browser compatibility, particularly Safari's H.264 limitation and ICE handling differences between Chrome and Firefox, requires careful testing and the use of adapter.js. - Licode's MCU architecture trades server-side scalability for client-side simplicity, and teams needing E2EE or massive scale may find SFU-based alternatives like LiveKit or managed platforms like VideoSDK more appropriate. ## Conclusion Licode WebRTC remains a relevant open-source option for developers who need full control over their real-time video infrastructure and prefer the MCU model's client-side simplicity. Its MIT license, C++ core, and JavaScript client API make it approachable for teams with mixed skill sets. The Docker quick-start image is the best way to evaluate whether Licode fits your use case before committing to a source build or production deployment. If you find that managing WebRTC infrastructure, TURN servers, and browser compatibility is more overhead than your team can absorb, VideoSDK offers a managed alternative with multi-platform SDKs, Prebuilt UI, and built-in recording and transcription. You can get started with VideoSDK for free and compare the developer experience directly. For Licode-specific questions, the Licode community forums on GitHub remain the primary support channel. What are you building with WebRTC? Drop a comment and let me know whether you are leaning toward Licode, another open-source platform, or a managed solution like VideoSDK.
Free $20 Balance for AI Voice Agents & Video Calls
FAQ
