protocol

Typed protobuf message classes and RPC definitions for LiveKit's WebRTC signaling protocol, generated straight from the canonical .proto source.

Library
npm
v1.51.0
146stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
90/100Excellent
Development Activity96
Maintenance100
Community84
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture88
Code Quality85
Innovation72
Learning Curve65

@livekit/protocol is the JavaScript/TypeScript build of the protobuf schema that defines LiveKit’s entire wire protocol — room and participant state, RTC signaling, egress/ingress, SIP, webhooks, analytics, and agent dispatch. Rather than hand-writing types for every message that crosses the network, LiveKit’s client and server SDKs import this package to get generated, always-in-sync classes straight from the .proto definitions that live in the same monorepo.

The repository is a Go-first monorepo: the .proto files under protobufs/ are the single source of truth, and this npm package is one of several generated outputs (alongside the Go module itself, which is consumed directly by LiveKit’s server and Go SDKs). The JS package is built with @bufbuild/protobuf and protoc-gen-es, producing ESM/CJS dual output with full .d.ts types for every message, enum, and service defined in the schema — including room/participant models, RTC signaling, egress and ingress jobs, SIP trunking, webhooks, analytics events, and agent dispatch/inference messages.

Because it’s generated rather than hand-authored, the package’s surface area tracks LiveKit’s actual server protocol release-for-release — new fields, messages, or RPC methods added to the platform show up here automatically on the next @bufbuild/protoc-gen-es regeneration, with no manual porting step and no drift between client-side types and what the server actually sends.

What You Get

  • Generated message classes - @bufbuild/protobuf-based classes for every LiveKit protocol message (room, participant, track, RTC signaling, models) with full TypeScript types.
  • Egress & ingress types - typed request/response/status messages for recording, streaming-out (egress) and streaming-in (ingress) jobs.
  • SIP protocol types - message definitions for LiveKit’s SIP trunking and telephony integration.
  • Webhook & analytics events - typed payloads for room/participant/track lifecycle webhooks and analytics event streams.
  • Agent dispatch & inference messages - protocol types for LiveKit Agents’ dispatch, session, and inference RPCs.
  • Dual ESM/CJS build - unbuild-produced output with .mjs/.cjs entry points and matching .d.mts/.d.cts type declarations.

Common Use Cases

  • Building a custom LiveKit client - construct and parse signaling messages when writing a client that talks to a LiveKit server outside the official client SDKs.
  • Server-side integrations - decode webhook payloads or analytics events sent by a LiveKit deployment in a Node.js backend.
  • Egress/ingress automation - type-safe construction of egress (recording/streaming) and ingress requests from custom tooling.
  • LiveKit Agents development - use the agent dispatch and inference message types when building custom agent workers or orchestration code.
  • Cross-SDK consistency - share the exact same message shapes the official livekit-client/livekit-server-sdk packages use, avoiding hand-maintained duplicate type definitions.

Under The Hood

Architecture The repository is structured around a single source of truth: .proto files under protobufs/ define every message and RPC service, and multiple language-specific packages (this npm package, the Go module at the repo root, and others) are generated from them via protoc/buf-based codegen (magefile.go’s Proto target, packages/javascript’s generate:proto script). The Go side additionally layers a custom RPC framework (psrpc, under rpc/) on top of the generated protobuf types for request/response and streaming calls between LiveKit services, while the JS package (packages/javascript) is a thin, generated-only surface — its src/index.js re-exports the @bufbuild/protobuf-generated modules under src/gen/ with no hand-written business logic. This means the npm package’s “architecture” is really the schema’s: message families are organized by domain (room/rtc/models, egress, ingress, sip, webhook, agent, analytics), and downstream SDKs depend on this package purely for shape, not behavior.

Tech Stack The JS package is built with @bufbuild/protobuf and @bufbuild/protoc-gen-es (targeting dts+js output), bundled via unbuild into dual ESM/CJS artifacts with generated .d.mts/.d.cts type declarations, and versioned via genversion. The wider monorepo is primarily Go (99%+ of repository bytes), using go.mod-declared dependencies including pion/webrtc for WebRTC internals, redis/go-redis for shared state, prometheus/client_golang and OpenTelemetry for observability, golang-jwt for auth token signing, and twitchtv/twirp alongside the custom psrpc package for RPC transport. Release management on the JS side goes through Changesets (.changeset/), publishing @livekit/protocol independently from the Go module’s own versioning.

Code Quality The Go portion of the monorepo is extensively tested — 69+ _test.go files cover auth (access tokens, grants, verification), webhooks, RPC metrics, and more, using testify and generated fakes (counterfeiter). Linting is enforced via golangci-lint with staticcheck’s full ruleset plus a custom depguard rule that forbids direct use of protojson in favor of an internal wrapper that defaults to discarding unknown fields — a deliberate schema-drift safeguard. CI runs build/test/generate workflows on every change (.github/workflows/buildtest.yaml, generate.yaml). The JS package itself has no dedicated test suite, which is expected for a purely generated codegen artifact with no hand-written logic to unit-test.

What Makes It Unique Unlike most protocol packages that are hand-maintained and drift from their server implementation over time, this package is mechanically regenerated from the exact .proto definitions that also produce LiveKit’s Go server and RPC layer — so the TypeScript types for a WebRTC SFU’s entire signaling surface (media negotiation, room/participant state, egress/ingress jobs, SIP, agent dispatch) stay provably in sync with what the server actually speaks, release for release.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search