MiroTalk SFU: a self-hosted mediasoup conferencing stack you run yourself
🏆 Self-hosted, open-source WebRTC video conferencing platform for real-time communication and collaboration. A modern alternative to Zoom, Google Meet, Jitsi Meet, and Microsoft Teams, powered by scalable SFU architecture with Mediasoup.
At a glance
- What is it?
- MiroTalk SFU is an AGPL-3.0 Node.js video conferencing server built on the mediasoup SFU. It is aimed at teams that want rooms on their own hardware, and its cost is operational: you own the TURN, TLS and port configuration that a hosted service would hide.
- Who is it for?
- Adopt MiroTalk SFU if you already run Node.js services, can terminate TLS in front of the app, and want one codebase for rooms, an SFU and RTMP egress. Do not adopt it if you need vendor support or cannot accept AGPL-3.0.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem MiroTalk SFU addresses, and the team it assumes
Hosted conferencing hands the media path, the participant list and the recording to a third party. MiroTalk SFU takes the opposite position: the README describes it as a platform you deploy on your own server to keep control over data, privacy and infrastructure. The stated audience is anyone who wants Zoom, Google Meet or Microsoft Teams style rooms without a per-seat plan, and the project lists self-hosting, unlimited rooms and unlimited time as the differentiators in its comparison table. That table is marketing copy written by the maintainer, not an independent measurement, so treat the 8K at 60fps and 133 language claims as product claims rather than verified figures. What is concrete is the deployment shape. This is a Node.js server that speaks WebRTC and needs a public address, a certificate and open UDP ports. A team without anyone comfortable owning that will find the operational surface larger than the feature list suggests.
Mediasoup SFU: what the server actually does with your media
The architecture named in the README is an SFU, a selective forwarding unit, implemented with mediasoup. In that model each participant uploads one stream to the server and the server forwards copies to the other participants. That is different from a mesh, where every client uploads to every other client, and from an MCU, where the server decodes, mixes and re-encodes. The SFU choice explains why the project can advertise high resolutions: the server forwards packets rather than transcoding them, so the ceiling is set by the client encoder and the available bandwidth, not by server CPU for mixing. It also explains the cost profile. Upload bandwidth scales with the number of participants because each one receives a separate forwarded stream, and the server's network interface becomes the constraint before its processor does. The README does not publish capacity numbers per vCPU, so any figure you see elsewhere should be treated as unverified.
Getting a room running from the six documented commands
The README gives an explicit quick start. Clone the repository, enter the directory, copy the two template files, install dependencies and start the process:
git clone https://github.com/miroslavpejic85/mirotalksfu.git cd mirotalksfu cp app/src/config.template.js app/src/config.js cp .env.template .env npm install npm start
The README then says to open https://localhost:3010, and the text is truncated at that point. Two things stand out. First, the split between app/src/config.js and .env is not explained in the material I have, so you have two files to inspect before changing anything, and guessing which one owns a given setting is a real source of confusion on first install. Second, the URL is HTTPS on port 3010 while the start command is plain npm start, which implies a certificate is expected; the README excerpt does not show where it comes from. Docker is listed as a deployment option and there is a mirotalk/sfu image on Docker Hub, but the excerpt does not include the compose file or run command, so I cannot state the exact flags. The documented feature set also includes OIDC authentication, JWT credentials, room passwords, a lobby, host protection and a REST API, each with its own configuration keys that the excerpt does not enumerate.
Where the self-hosted model stops being the right answer
The failure modes here are network and operational, and they are the ones that bite in production. WebRTC needs a reachable media path. On a host behind NAT, or for participants on restrictive corporate networks, you need a TURN relay, and the README excerpt does not document one. Without it, some participants simply fail to connect while others work, which is a difficult symptom to diagnose from a support ticket. TLS is the second constraint: browsers require a secure context for camera and microphone access, so the HTTPS URL in the quick start is not optional, and certificate renewal becomes part of your maintenance. Third, the licence. AGPL-3.0 is a strong copyleft licence, and if you modify the server and expose it to users over a network, the source obligations attach to your modified version. That is a real consideration for anyone embedding this in a commercial product; the README also points to a paid one-time fee licence on Codecanyon, which is the route the maintainer offers for that case. I am not a lawyer and this is not legal advice, so read the licence text and the Codecanyon terms yourself. Finally, there is no vendor to escalate to. When a call drops at scale, the person debugging it is you.
How this differs from Jitsi Meet, the obvious comparison
Jitsi Meet is the other well-known open source conferencing stack, and the README names it directly as something MiroTalk SFU is an alternative to. The difference that matters is the packaging. Jitsi is a multi-component deployment: a Videobridge for media, Prosody for signalling, Jicofo for conference focus, plus a web front end, and the standard install path is a set of Debian packages with their own configuration files. MiroTalk SFU is a single Node.js application started with npm start, with configuration in app/src/config.js and .env, which is a much shorter path from clone to a running room. That simplicity has a cost: Jitsi's components can be scaled and replaced independently, and its deployment has a wider body of operational documentation built up over years. Choosing between them is largely a question of whether you want one process to reason about or a set of services you can scale separately. MiroTalk SFU also bundles RTMP streaming for OBS and a REST API in the same codebase, which Jitsi handles through separate tooling.
Maintenance, upgrades and what AGPL-3.0 means for a fork
You are running from the main branch of a repository that is actively pushed to, with no releases retrieved in the material I have. That means upgrades are a git pull plus npm install plus a restart, and there is no tagged version to pin against. The practical consequence is that you should track the commits you deploy and keep your local changes to app/src/config.js and .env rather than editing source files, so a pull does not conflict. The two template files exist precisely to support that pattern: copy them once, keep your values there, and treat the rest of the tree as upstream. On licensing, AGPL-3.0 requires that users interacting with a modified version over a network be offered the corresponding source. If your deployment is unmodified and internal, the obligation is easier to satisfy; if you fork the interface or the server logic and expose it to customers, plan for how you will publish those changes, or take the commercial licence route the README links to. Docker images are published under the mirotalk/sfu name, so a pinned image tag is another way to control what you are running, though the excerpt does not list available tags.
What to verify before you commit to it
Three checks come before any rollout. First, confirm how TLS is terminated on port 3010 in your setup; the quick start assumes HTTPS and the excerpt does not show the certificate path, so read the self-hosting documentation linked from the README. Second, test connectivity from a restricted network, not just from your office, to find out whether you need a TURN server before your first real meeting rather than during it. Third, read app/src/config.template.js and .env.template end to end and map every key you intend to set to the right file, because the documentation excerpt does not draw that line for you. If those three checks pass and you have someone who owns the server, MiroTalk SFU is a coherent choice: one Node.js process, mediasoup forwarding, RTMP output and a REST API in the same tree. If they do not, the hosted services the README positions against are cheaper than the engineering time the self-hosted path will consume.
Editorial conclusion
Adopt MiroTalk SFU if you already run Node.js services, can terminate TLS in front of the app, and want one codebase for rooms, an SFU and RTMP egress. Do not adopt it if you need vendor support or cannot accept AGPL-3.0. Before rolling it out, clone the repository, diff app/src/config.template.js and .env.template against your environment, and confirm which of the two files holds the settings you intend to change.
Community notes