The Problem

Developers building live‑audio/video or AI‑driven multimodal experiences need a self‑hosted, production‑grade SFU that can be started, scaled, and extended without pulling in a monolithic stack. Maintaining real‑time media pipelines, participant routing, and credential handling is error‑prone and hard to test in isolation.

What This Does

The repository bundles four Go‑centric projects that together implement a WebRTC SFU server, routing layer, and supporting agents. The core server lives in cmd/server/ (main.go, commands.go) and wires together the packages under pkg/—most notably pkg/rtc/ (media tracks, participants, rooms) and pkg/routing/ (local‑router, Redis router, node stats). Configuration is read from a YAML file (config‑sample.yaml) and the binary can be run directly or via the provided Dockerfile.

How It Is Wired

Execution begins at cmd/server/main.go:123main. After a brief init (line 119) it calls startServer (line 247). startServer:

  1. Parses the YAML config (pkg/config/config.go) – a filesystem read path (os.Open).
  2. Validates TLS/JWT keys (ValidateKeys in pkg/config/config.go) – another file read.
  3. Instantiates a localrouter.Start (pkg/routing/localrouter.go:128).

Start creates the routing graph used by every participant, then spawns the SFU (pkg/rtc/room.go, pkg/rtc/participant.go). The most‑used internal functions are:

  • recordInvocation – called from 347 places, making it a high‑impact change point.
  • Load, ID, Store, Run, Add, Close – each referenced >50 times across the codebase.

The call graph shows recordInvocation as a hub; altering its signature ripples through >300 call sites. No circular import cycles were detected, but three files (pkg/rtc/participant.go, pkg/rtc/room.go, pkg/rtc/subscriptionmanager.go) each exceed 3 k lines, raising the blast radius for any modification.

External effects:

  • Filesystem – config load (os.ReadFile), key validation (os.Open).
  • NetworkStart performs an outbound http.Get (e.g., health checks).
  • Subprocessmain may invoke external commands via cmd.Run.

No database drivers appear in the static call graph, but several functions are marked as “reads or writes a database” by the analysis layer, suggesting future extensions.

How To Use It

# Clone the repo (use the exact URL)
git clone https://github.com/moses-y/livekit
cd livekit

# Build the server binary
go build -o livekit-server ./cmd/server

# Or build the Docker image (Dockerfile is present)
docker build -t livekit:local .

Configuration:

  • Copy config-sample.yaml to config.yaml.
  • Supply TLS cert/key paths and a JWT secret inside the file (the server validates them at startup).

Run:

# Binary
./livekit-server --config config.yaml

# Docker
docker run -p 7880:7880 -v $(pwd)/config.yaml:/app/config.yaml livekit:local

The server listens on the port defined in the config (default 7880) and advertises a REST endpoint for room/participant management.

Real‑World Use

A typical deployment places the LiveKit container behind a TURN server and a load balancer. An application creates a room via the REST API, obtains a JWT from the server (pkg/clientconfiguration), and the client SDKs (JS, iOS, Android) connect to the SFU for media exchange. Agents in pkg/agent/ can be added to the routing graph to inject AI processing (e.g., speech‑to‑text) into a live session.

Code Health & Issues

Measured static findings (high‑severity)

  • Deep nesting – 45 files (e.g., pkg/rtc/mediatrack.go, pkg/rtc/participant_sdp.go) reach 8‑level indentation, making control flow hard to follow.
  • Duplicated code – 1 682 six‑line blocks repeated across ~340 files (e.g., bootstrap.sh, install-livekit.sh, cmd/server/*.go).
  • Oversized files – 14 files exceed 3 k lines (pkg/rtc/participant.go, room.go, subscriptionmanager.go), increasing change impact.

Code‑health audit (GitHub‑Actions/Docker)

SeverityIssueLocation
HighPin third‑party GitHub Actions to commit SHA.github/workflows/*.yaml (e.g., livekit/slack-notifier-action@main)
MediumPin Docker base image by digestDockerfile (uses golang:1.25-alpine)
MediumAdd dependency‑vulnerability scan to PRs.github/workflows/buildtest.yaml (no scan step)
MediumSet persist-credentials: false on checkout.github/workflows/buildtest.yaml (checkout step)
MediumRun container as non‑root userDockerfile (no USER directive)
LowDefine timeout-minutes for workflow jobs.github/workflows/buildtest.yaml (jobs missing timeout)

All other hygiene checks (tests, CI, licence, lockfile) are present.

The Bottom Line

LiveKit provides a mature, Go‑based SFU with a clear entry point and Docker support, but the codebase suffers from deep nesting, duplicated helpers, and several megafile hotspots that inflate change risk. It is suited for teams comfortable with Go who need a customizable real‑time media backend, provided they allocate effort to refactor the high‑impact modules and tighten the CI/CD supply chain.