Rhema
Architecture

Tech Stack

Frontend, backend, ML, database, broadcast, and STT layers — the libraries Rhema is built on and the reasons we picked them.

LayerTechnologies
FrontendReact 19, TypeScript, Tailwind CSS v4, shadcn/ui, Zustand, Vite 7
BackendTauri v2, Rust workspace with seven crates
AI / MLONNX Runtime (Qwen3-0.6B embeddings), Aho-Corasick, Fuse.js
DatabaseSQLite via rusqlite (bundled) with FTS5
BroadcastNDI 6 SDK via dynamic loading (libloading FFI)
STTLocal Whisper via whisper.cpp, or Deepgram WebSocket + REST (tokio-tungstenite)

Layered architecture diagram — React frontend over Tauri IPC, Rust workspace below, with NDI / STT / SQLite as external surfaces

Layer-by-layer view of the stack: React + Tailwind on top, Tauri IPC bridge in the middle, the Rust workspace below, and the external surfaces (NDI sender, STT engines, SQLite-on-disk) at the edges. Click to expand.

Frontend

React 19 + Vite 7

Modern React with concurrent features. Vite 7's dev server hot-reloads in under a frame.

Tailwind CSS v4 + shadcn/ui

Utility-first styling with shadcn primitives layered on Radix. Custom components live in src/components/ui.

Zustand stores

Audio, transcript, Bible, queue, detection, broadcast, and settings each have their own slice — no Redux ceremony.

Backend

The Rust side is a Cargo workspace of seven crates, each with a single clear responsibility. See the Rust crates page for the breakdown.

tauri = "2.10.3" wires Rust commands to React via a typed IPC surface. Workspace MSRV is rust-version = "1.77.2". The webview is locked down with a restrictive CSP to prevent script injection and unauthorized data exfiltration.

ML / detection

The detection pipeline is intentionally heterogeneous:

  • Aho-Corasick (aho-corasick = "1") for direct reference parsing — compiled once, scans in linear time with negligible memory.
  • Qwen3-Embedding-0.6B for semantic search, exported to ONNX and quantized to INT8 (via optimum-cli onnxruntime quantize --arm64) so a normal CPU keeps up.
  • ONNX Runtime through the ort = "2.0.0-rc.12" Rust crate for inference (gated behind the onnx feature on rhema-detection).
  • Brute-force cosine similarity over the embedded verses (~31k × 1024 dims). The file semantic/hnsw_index.rs is named after a future plan; today it scans linearly because the dataset is small enough that the simpler approach wins.
  • Fuse.js on the frontend for instant fuzzy search over the recent transcript context (src/lib/context-search.ts).

Database

A single SQLite database with FTS5 holds every translation, cross- reference, and metadata table. We use rusqlite with the bundled feature so the binary is self-contained — no system SQLite required.

Broadcast

The NDI 6 SDK is loaded dynamically via libloading so the binary doesn't depend on the SDK at link time. This keeps the app legally distributable and lets it run fine without NDI installed (the broadcast surface just doesn't appear).

STT

Two engines, one transport:

  • Whisper runs locally via whisper.cpp, compiled by bindgen during the first build.
  • Deepgram streams over a WebSocket using tokio-tungstenite, with a REST fallback that uploads short windows when the socket drops.

Both feed a unified transcript stream so the rest of the pipeline doesn't care which engine is active.

On this page