The Problem
Users who need on‑device speech‑to‑text often resort to cloud services that stream audio to remote servers, exposing raw voice data and incurring latency. When a local, privacy‑first engine is required—e.g., for confidential note‑taking or offline workflows—there are few turnkey, cross‑platform solutions that bundle a neural model, UI, and post‑processing.
What This Does
murmure ships a Tauri desktop wrapper (Rust entry points src‑tauri/src/main.rs and src‑tauri/src/lib.rs) around a React/Next.js front‑end (src/). The UI lives in index.html and src/overlay/index.html. Audio is captured via the bundled resources (resources/audio/start_record.mp3, stop_record.mp3) and sent to the on‑device Parakeet model (downloaded at runtime, not in the repo). Transcription results are optionally refined by a local LLM through the LLM‑connect feature (src/features/llm-connect/*). Settings, dictionaries, and language packs are stored under src/features/settings/* and resources/cc‑rules/.
How It Is Wired
- Process start – The OS launches the Tauri binary built from
src-tauri/src/main.rs. - Tauri bridge –
src-tauri/src/lib.rsregisters JavaScript APIs that the front‑end can call (e.g., start/stop recording, load model). - Front‑end boot – React renders
src/pages/_app.tsx(implicitly via Next.js) and mounts the UI defined insrc/components/*. The most‑connected UI module issrc/features/llm-connect/hooks/use-llm-connect, imported by seven other modules but importing none, making it a leaf of the import graph. - Audio flow – UI actions invoke the Tauri‑exposed
recordAudioAPI, which streams raw PCM to the Rust side. The Rust code (insrc-tauri/src/) writes the stream to a temporary file and calls the Parakeet inference binary (outside the repo). - Transcription result – The Rust side returns a JSON payload to the front‑end, which updates state in
src/features/home/home.tsx. - LLM post‑processing – If enabled,
src/features/llm-connect/llm-connect.helpers.tsformats the transcript and calls the local LLM via a spawned process; the result is merged back into the UI. - Shutdown / cleanup – End‑to‑end test utilities (
e2e-tests/helpers/visual-helpers.js) definecloseTauriDriver, invoked from two places; the internal call graph showsonComplete → closeTauriDriver. This is the only resolved intra‑repo call edge, indicating limited internal coupling.
Hot‑spot modules – src/components/sidebar.tsx (735 lines) and several rule‑form components have depth‑9 nesting, making them fragile change points. The import graph contains 120 modules, 111 edges, with no circular dependencies, so adding features is unlikely to cause dead‑ends, but deep nesting and duplicated 6‑line blocks (156 occurrences across 15 files) increase cognitive load.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/murmure
cd murmure
# Install JavaScript dependencies (pnpm lockfile present)
pnpm install
# Build the Tauri app (uses the Cargo.toml in src-tauri)
pnpm tauri dev # runs `cargo build` and launches the desktop UI
No environment variables are required for the core flow. The only external artifact is the Parakeet model, which the app downloads on first run (the download URL is hard‑coded in the Rust code). To change language packs, edit the text files under resources/cc-rules/ and resources/cc-rules/lang.txt.
Real‑World Use
A security‑aware analyst runs Murmure on a Windows laptop to dictate incident reports. The analyst clicks the UI “record” button, the Tauri bridge streams audio to the local model, and the transcript appears instantly. A post‑process hook (use-llm-connect) rewrites the text to fit the organization’s incident‑report template, all without any network traffic.
Code Health & Issues
Measured findings (static analysis)
- HIGH – Deep nesting – files
src/components/rule-form-fields.tsx,src/components/sidebar.tsx,src/components/rule-card.tsxhave max indentation depth 9. - HIGH – Duplicated code – 156 repeated 6‑line blocks across 15 files (e.g.,
src/features/home/history/history.tsx). - MEDIUM – Oversized file –
src/components/sidebar.tsxis 735 lines.
Code‑health audit (9 items)
- HIGH – Pin GitHub Actions to commit SHA – workflow files use tags like
signpath/github-action-submit-signing-request@v2. - HIGH – Upgrade vulnerable dependencies –
tokio@1,once_cell@1,tar@0.4,tauri@2etc. have published CVEs. - HIGH – CI does not run tests – four workflows lack a test step despite 14 test files.
- MEDIUM – Enable Dependabot/Renovate – no auto‑update bot configured.
- MEDIUM – Add dependency‑vulnerability scan – no
dependency-review-actionor similar. - MEDIUM – Move large binaries to Git LFS –
e2e-tests/voices/test_en.wav(6.7 MiB) andtest_fr.wav(5.6 MiB). - MEDIUM – Set
persist-credentials: falseon checkout – workflowbuild-linux.ymlkeeps the token in.git/config. - MEDIUM – Expand test coverage – only 6 test files cover ~3 % of source.
- LOW – Add
timeout-minutesto workflow jobs – two CI jobs lack explicit timeouts.
The Bottom Line
murmure delivers a functional, offline speech‑to‑text desktop app with a clean UI and LLM post‑processing, but the codebase suffers from deep nesting, duplicated snippets, and an oversized sidebar component that raise maintenance risk. Security‑wise, several high‑severity dependency advisories and CI gaps need remediation before the project is production‑ready. It is suitable for teams comfortable fixing the highlighted code‑health issues and who need a self‑hosted transcription pipeline.