Rust Crates
Seven workspace crates, each with one job — audio, STT, Bible, detection, broadcast, API, and notes.
The backend is split into focused crates so each layer can be tested in isolation and replaced without rewiring the rest. Inter-crate dependencies follow a strict downward fan-out from the API layer.
Crate overview
| Crate | Responsibility |
|---|---|
rhema-audio | Audio device enumeration, capture, voice activity detection (cpal) |
rhema-stt | Deepgram STT WebSocket + REST fallback; Whisper local engine |
rhema-bible | SQLite Bible database, FTS5 search, cross-references |
rhema-detection | Verse detection pipeline: direct, semantic, quotation, ensemble merger, sentence buffer, sermon context, reading mode |
rhema-broadcast | NDI video frame output via FFI |
rhema-api | Tauri command API layer — the only crate that touches Tauri |
rhema-notes | (placeholder for upcoming sermon notes feature) |
Why split this way
Each crate maps to a clear external responsibility:
-
rhema-audioowns the operating system. Anything device-specific — enumeration, capture buffers, sample-rate conversion, VAD — lives here so the rest of the workspace can pretend audio is just bytes. -
rhema-sttowns network and local STT. Both Whisper and Deepgram emit the same transcript event type, so the consumer doesn't know (or care) which engine is wired in. -
rhema-bibleowns the database. FTS5 query construction, cross-reference joins, BM25 ranking — all of it is encapsulated behind a small set of typed read paths. -
rhema-detectionowns the pipeline. It depends onrhema-biblefor verse text and reference lookup, but otherwise it's self- contained and testable with synthetic transcripts. -
rhema-broadcastowns NDI. It loads the SDK dynamically and exposes astart_sender/send_frame/stop_senderAPI. Other crates don't include the FFI surface at all. -
rhema-apiowns Tauri. Every Tauri command lives here. Other crates don't depend on Tauri, which means the workspace can be built and tested as plain Rust without the Tauri shell. -
rhema-notesis a placeholder. Itslib.rsreads "Planned: Claude API integration, sermon note generation, and PDF/Markdown export" — none of that is implemented yet.
Dependency graph
The fan-out from rhema-api down through audio, stt, bible, detection, broadcast, and notes. Edges are strictly downward; no cycles. Click to expand.
rhema-api
├── rhema-audio
├── rhema-stt ───→ rhema-audio
├── rhema-bible
├── rhema-detection ───→ rhema-bible
├── rhema-broadcast
└── rhema-notesThe graph is strictly downward — no cycles, no horizontal
dependencies. This is enforced by the workspace Cargo.toml and is
the property that keeps incremental builds fast and individual crates
testable.
Feature flags
Two crates are gated behind Cargo features so the workspace stays buildable on minimal toolchains:
rhema-sttexposes awhisperfeature (whisper-rs = "0.16",optional = true). The Deepgram path is always available.rhema-detectionexposesonnx(turns onort = "2.0.0-rc.12") andvector-searchfeatures.
The default crate features in src-tauri/Cargo.toml enable both ONNX
and vector search, so the standard tauri dev workflow gets the full
detection pipeline.
Testing
Pipeline crates have inline #[cfg(test)] modules with curated
transcript fixtures so detection behavior is asserted on known
inputs.
Run the workspace test suite from the repo root:
cargo test --workspaceThe frontend test surface uses Vitest (bun run test).