RepoPilot

How do their APIs compare?

About grvydev/project-lightspeed · 2 messages · last activity 9/8/2026

Question

How do their APIs compare?

RepoPilot

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:

  1. 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 in handle_command [ingest/src/connection.rs:L294-L333], with responses sent back over a framed TCP connection via a FrameCommand::Send enum [ingest/src/connection.rs:L14-L17] and handle_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].

  2. WebRTC signaling API (Go, webrtc/): The Go server exposes a plain HTTP server with a single /websocket endpoint [webrtc/main.go:L45-L127] that upgrades to WebSocket. Signaling is JSON messages with an event field (offer, answer, candidate, info) — there's no REST/JSON-RPC schema, just ad hoc message shapes matched with switch (msg.event) on the frontend [frontend/src/App.js:L32-L118] and mirrored server-side (e.g. candidate messages built into a ws.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, and Response enums (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::Version to 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 via socket.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 --json flag that serializes the typed response via serde_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-level niri_ipc::CastTarget via make_ipc()/matches() [src/niri.rs:L597-L632] — showing a clear internal/external type boundary that Lightspeed's protocols don't really have (its enums like FtlCommand are used directly rather than mapped to/from a separate public schema).

Summary of the contrast

Aspectproject-lightspeedniri
Protocol styleAd hoc JSON-over-WebSocket + custom FTL text prot

Want to ask your own question?

Open chat for grvydev/project-lightspeed

Public 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.