How do their APIs compare?
How do their APIs compare?
About grvydev/project-lightspeed · 2 messages · last activity 9/8/2026
These two projects don't really have a comparable "API" concept — they solve different problems and expose fundamentally different surfaces. Here's how they break down:
grvydev/project-lightspeed: a WebSocket signaling API + FTL ingest protocol
Lightspeed's "API" is really two informal wire protocols glued together by its three components:
-
FTL ingest protocol (Rust,
ingest/): This is a command-based text protocol OBS speaks to the ingest server. Commands are modeled as an enum —FtlCommand::{HMAC, Connect, Ping, Dot, Attribute, Disconnect}[ingest/src/ftl_codec.rs:L8-L16] — and handled in a big match statement inhandle_command[ingest/src/connection.rs:L294-L333], with responses sent back over a framed TCP connection via aFrameCommand::Sendenum [ingest/src/connection.rs:L14-L17] andhandle_frame_command[ingest/src/connection.rs:L182-L213]. It's a stateful, connection-oriented protocol, not a request/response API in the REST sense — unhandled commands just log a joking warning ("Tell GRVY to quit his day job") [ingest/src/connection.rs:L334-L341]. -
WebRTC signaling API (Go,
webrtc/): The Go server exposes a plain HTTP server with a single/websocketendpoint [webrtc/main.go:L45-L127] that upgrades to WebSocket. Signaling is JSON messages with aneventfield (offer,answer,candidate,info) — there's no REST/JSON-RPC schema, just ad hoc message shapes matched withswitch (msg.event)on the frontend [frontend/src/App.js:L32-L118] and mirrored server-side (e.g. candidate messages built into aws.WebsocketMessage{Event: ws.MessageTypeCandidate, ...}[webrtc/main.go:L246-L285]). It's a bespoke, minimal signaling protocol — no versioning, no schema validation visible in these excerpts.
There's no formal external API surface documented (no OpenAPI/gRPC/etc.), and per the RepoPilot verdict, the project is stale (last commit ~3 years ago), so this protocol has not evolved recently.
niri-wm/niri: a structured, versioned IPC protocol
Niri's IPC is far more deliberately designed:
- It's built around explicit
Msg,Request, andResponseenums (e.g.Msg::Version,Msg::Outputs,Msg::FocusedWindow) matched exhaustively in the client [src/ipc/client.rs:L138-L177]. - It includes first-class version negotiation: the client detects likely version mismatches from error types, reconnects and sends
Request::Versionto compare compositor vs. CLI versions, and prints an explicit warning telling the user to restart niri after an update [src/ipc/client.rs:L58-L97, L98-L137]. Lightspeed has no equivalent versioning/compatibility handling. - It supports a structured event stream (
Event::WorkspacesChanged,Event::WindowOpenedOrChanged,Event::WindowClosed, etc.) read viasocket.read_events()in a loop [src/ipc/client.rs:L418-L457], giving consumers a typed, subscribable feed — Lightspeed's WebSocket only pushes a small fixed set of signaling/info events. - Every response supports a
--jsonflag that serializes the typed response viaserde_json, so the IPC has both a human-readable CLI mode and a structured machine-readable mode [src/ipc/client.rs:L138-L157, L418-L426]. - Internally, niri also exposes IPC-facing types like
CastTarget, which converts between an internal compositor representation and the wire-levelniri_ipc::CastTargetviamake_ipc()/matches()[src/niri.rs:L597-L632] — showing a clear internal/external type boundary that Lightspeed's protocols don't really have (its enums likeFtlCommandare used directly rather than mapped to/from a separate public schema).
Summary of the contrast
| Aspect | project-lightspeed | niri |
|---|---|---|
| Protocol style | Ad hoc JSON-over-WebSocket + custom FTL text prot |
Want to ask your own question?
Open chat for grvydev/project-lightspeedPublic Q&A. Generated by RepoPilot from the actual source of grvydev/project-lightspeed. AI answers can be incomplete or stale — verify before relying on them.