Open-source church presentation software. A lightweight, keyboard-first alternative to ProPresenter and EasyWorship.
Quick Start · Features · Development · Architecture · Building
Rhema is a Tauri v2 desktop app (React 19 frontend, Rust backend) built for live church services. It manages your service queue, presents Bible verses and custom content to a stage display, and outputs to broadcast via NDI — without requiring a subscription or an internet connection.
- Tolerant reference parser — type
Jn 3 16,Jn 3:16, or1 John 3 16; colon, space, or tab all work - 10 bundled translations — KJV, NIV, ESV, NASB, NKJV, NLT, AMP, Spanish (SpaRV), French (FreJND), Portuguese (PorBLivre)
- Full-text search — phrase and keyword search across all translations (SQLite FTS5, BM25 ranking)
- Cross-reference lookup — 344,800+ cross-reference pairs from openbible.info
- Chapter context — selected verse shows surrounding chapter for navigation
- Instant translation switch — swap versions mid-service; arrow-key navigation resumes automatically
- Service queue — drag-and-drop ordering, named groups, session save/load, auto-named on first item, per-chapter Bible dedup
- Keyboard-first —
Entersends the staged item live;←/→walk slides; no mouse required - Stage display — dedicated second-screen window with current slide, next-up, and clock
- NDI broadcast output — configurable resolution, 24/30/60 fps, three alpha modes
- Theme designer — canvas-based overlay editor (background, text, position, shadow, outline)
- Preview / staging — see what you're about to present without changing the live output; Go Live button promotes staged item directly
- Live output toggle — click the canvas to take output on/off air; Rhema logo shows when off-air
- Bible — search, browse, stage, and present any verse or passage; arrow keys walk verse-by-verse
- Text — TipTap rich-text editor with H1/H2/H3, bold, italic, underline, alignment;
Ctrl+Enterinserts a slide break; per-slide play buttons; saved snippets (persistence in B2) - Songs — song library with full-song multi-slide staging; click any section to start from there, arrow keys continue through remaining sections; section drill-down view
- Media — image asset library with contain/cover/stretch fit modes; canvas resize on import (backend in B2)
- Browser dev mode — full UI runs in any browser via the dev Bible bridge (no Tauri build needed for UI work)
- Remote control — OSC and HTTP API for Stream Deck, TouchOSC, and automation
| Tool | Version | Notes |
|---|---|---|
| Bun | 1.x | Package manager and script runner — always use bun, never npm |
| Rust | stable ≥ 1.77.2 | rustup toolchain install stable |
| Tauri v2 system deps | — | Platform WebView libraries |
git clone <repo-url>
cd rhema
bun installbun run download:bible-data # download translations + cross-references
bun run build:bible # build data/rhema.db (~98 MB)Option A — browser mode (fastest, no Rust compile):
# Terminal 1 — Bible API bridge
DEV_BRIDGE_TOKEN=<your-token> bun scripts/dev-bible-bridge.ts
# Terminal 2 — Vite frontend
bun run devThen open http://localhost:3000 in a browser.
The bridge serves Bible commands from data/rhema.db over HTTP. Set a token in .env.local:
VITE_DEV_BRIDGE_TOKEN=your-secret-token
and start the bridge with DEV_BRIDGE_TOKEN=your-secret-token.
Option B — full Tauri app (with Rust backend):
bun run tauri devThis compiles the Rust backend and opens the app in a native webview. First run takes a few minutes.
bun run tauri buildProduces a platform installer (.msi on Windows, .dmg on macOS, .AppImage/.deb on Linux) in src-tauri/target/release/bundle/.
Note: the default build excludes AI/ML dependencies (Whisper STT, ONNX detection). To include them:
bun run tauri build -- --features whisper,detection(requires CMake + libclang + model files).
| Script | What it does |
|---|---|
bun run dev |
Start Vite dev server on port 3000 |
bun run typecheck |
TypeScript type-check (tsc --noEmit) |
bun run test |
Run Vitest unit tests |
bun run lint |
ESLint |
bun run format |
Prettier |
bun run tauri dev |
Full Tauri app (Rust + React) |
bun run tauri build |
Production installer |
bun run download:bible-data |
Download translations + cross-references |
bun run build:bible |
Build data/rhema.db from sources |
bun run e2e |
Playwright end-to-end tests |
.env.local (gitignored, create manually):
VITE_DEV_BRIDGE_TOKEN=your-secret-token # required for browser dev mode
.env.template shows all available variables:
VITE_AI_FEATURES=false # set to true to enable AI panels (requires --features whisper,detection)
DEEPGRAM_API_KEY= # cloud STT (AI feature, off by default)
bun run test # unit tests (Vitest) — ~200 tests, < 3s
bun run e2e # Playwright shell tests (requires running dev server)
cd src-tauri && cargo test # Rust unit tests| Key | Action |
|---|---|
Enter |
Send staged item live |
← → |
Previous / next slide / verse (guarded — won't fire inside inputs or editors) |
| Click live canvas | Toggle on/off air |
| Any reference | Type Jn 3 16 in Bible search to jump directly |
rhema/
├── src/ # React 19 frontend
│ ├── components/
│ │ ├── browser/ # Tab content: bible, text, song, media browsers
│ │ ├── layout/ # Dashboard shell (queue + preview + live + browser)
│ │ ├── panels/ # Preview/staging, live output
│ │ ├── shell/ # Top bar, service queue
│ │ └── ui/ # shadcn/ui + custom components
│ ├── hooks/ # useBible, useBroadcast, etc.
│ ├── lib/
│ │ ├── bible-ref-parser.ts # Tolerant reference parser (space/colon/tab, numbered books)
│ │ ├── slide-split.ts # Text → slide array (blank-line split)
│ │ ├── verse-renderer.ts # Canvas 2D slide renderer
│ │ └── keyboard.ts # shouldIgnoreGlobalKey guard
│ ├── stores/ # Zustand: bible, queue, broadcast, settings
│ └── types/ # ContentItem union, Slide, etc.
├── src-tauri/ # Rust backend (Tauri v2)
│ └── crates/
│ ├── bible/ # SQLite DB, FTS5 search, cross-references
│ ├── broadcast/ # NDI video frame output (FFI)
│ ├── api/ # Tauri command API layer
│ ├── stt/ # Deepgram/Whisper STT (off by default, --features whisper)
│ ├── audio/ # Audio capture (off by default, --features whisper)
│ └── detection/ # Verse detection pipeline (off by default, --features detection)
├── e2e/ # Playwright tests
├── scripts/
│ └── dev-bible-bridge.ts # HTTP shim for browser dev mode
├── data/ # Bible data pipeline scripts
└── screenshots/ # QA screenshots
All content (Bible verses, song sections, text slides, media) flows through a single ContentItem union:
type ContentKind = "verse" | "lyrics" | "media" | "text"
type ContentItem = VerseContentItem | LyricsContentItem | MediaContentItem | TextContentItemEach item carries slides: Slide[]. The queue, preview panel, live output, and stage display all consume ContentItem generically — adding a new content type only requires a new browser tab and a factory function.
AI features are present in the codebase but excluded from the default build:
| Flag | Enables |
|---|---|
| (default) | Bible search, all content browsers, NDI output, remote control |
--features whisper |
Local Whisper STT, Deepgram cloud STT, audio capture |
--features detection |
ONNX verse detection, semantic/embedding search |
--features whisper,detection |
Full AI stack |
| Milestone | Status |
|---|---|
| M1 — Presentation shell (queue, preview, live, stage display) | ✅ Done |
| M1+ — AI feature-gate, shell contract, content browser tab designs | ✅ Done |
| v1.0 — Full UX polish: keyboard nav for all content types, queue sessions, live toggle, image processing, theme fixes | ✅ Done |
B2 — Text snippet persistence, Songs backend (rhema-songs), Media backend (rhema-media) |
🟡 Next |
| M3 — Windows installer, auto-update | ⬜ Planned |
| M4 — NDI improvements, video media | ⬜ Planned |
git clone <repo-url>
cd rhema
bun install
bun run download:bible-data && bun run build:bible
bun run dev # browser mode, fastest feedback loop- Use bun, not npm. The lockfile is
bun.lock; npm will drift it. - One concept per commit. No AI-attribution trailers.
- Gates:
bun run typecheck+bun run testmust be clean before opening a PR. - Run
cd src-tauri && cargo buildto verify the Rust default build.
MIT