Development
Commands from package.json
bun install
bun run dev # Vite frontend dev server
bun run harness # Vite server for /harness.html
bun run build # build themes, type-check, Vite build
bun run build:themes # bundle builtin themes to src-tauri/themes/
bun run tauri dev # Tauri dev app
bun run tauri build # production Tauri build
bun run test:run # Vitest once
bun run test:coverage # Vitest coverage
bun run test:e2e # Playwright tests
bun run test:all # Vitest + Playwright
bun run test:rust # cargo build examples + cargo test
bun run lint # ESLint over src/**/*.ts(x)
Rust tests can also be run directly:
cd src-tauri && cargo test
End-to-end tests
bun run test:e2e runs the Playwright suite (e2e/*.spec.ts, config in
playwright.config.ts). Playwright starts the Vite dev server on
http://localhost:5173 and drives Chromium against the frontend with a
mocked Tauri backend, so most of the suite runs headless on any host with
Playwright’s Chromium installed (bunx playwright install chromium).
The suite is maintained and passing: a representative run is 108 passed,
27 skipped, 0 failed. The skipped tests are gated on purpose — the
macOS-native overlay/AppKit tests (test.skip(process.platform !== "darwin")),
the X11-display system-tray screenshot, and the legacy webview-overlay
describe.skip blocks that were superseded by the native egui overlay.
They are not failures.
E2E is not wired into automatic CI (a separate decision about CI
runtime/cost). Run it manually before tagging a release — see the release
checklist in .pi/skills/voxis-deploy/SKILL.md.
Architecture
Frontend code lives in src/ and uses React 18, TypeScript, Vite, React Router, and Tauri invoke wrappers. Public routes/pages are Settings (/settings), History (/ and /history), Dictionary (/dictionary), and Onboarding (/onboarding).
Important frontend areas:
src/lib/commands.tsandsrc/bindings.ts— invoke wrappers and generated bindings.src/lib/settingsRegistry.tsandsrc/lib/constants.ts— settings UI registry and option lists.src/hooks/— async data, settings, audio devices, recording, overlay state, provider, and theme hooks.src/components/— layout plus dictionary, history, settings, and spectrum components.src/theme-engine/— ThemeHost, contract (apiVersion1), builtin sources, and renderers.src/overlay.tsx— overlay webview entry point and pointer recording wiring.
Backend code lives in src-tauri/ and uses Rust with Tauri v2. There are two binaries: voice (main app) and typing_bench (auto-type latency benchmark).
Important modules include:
audio/— recording via CPAL, audio levels, VAD, and WAV encoding.orchestrator/— hotkey-to-transcription workflow, queueing, overlay updates, post-processing, and output.transcription/— Whisper-compatible HTTP client (default Groq transcription URL; custom endpoints only viaapi_url_override).docker-compose.selfhost.ymlat the repo root is a thin wrapper for running a self-hosted, protocol-compatible transcription server locally for this client — see Self-Hosted Transcription.output/— clipboard, paste shortcuts, auto-typing, and auto-submit.hotkey/— low-level keyboard input via rdev.storage/— config, history, dictionary, corrections, provider/prompt, failed-audio, theme, and debug storage under the platformvoxisconfig directory.theme_engine/andoverlay_native/— manifest/script loading and overlay window handling (cross-platform webview backend; standard size 172×36 logical px unless a theme sets validoverlay_width/overlay_height).llm/andlearning/— optional LLM post-processing and dictionary learning suggestions.commands/— Tauri commands exposed to the frontend.
Data flow
- Hotkey press →
hotkey::HotkeyListener→Orchestrator::on_hotkey_pressed()startsAudioRecorder. - Hotkey release (hold mode) or second tap (toggle mode) queues audio in
TranscriptionQueue. - Queue worker: transcribe → dictionary → optional LLM → clipboard/auto-type output.
- Frontend receives
state-changedanderrorevents from the backend.
GitHub Pages docs
The docs site is in docs-site/ and is built by .github/workflows/pages.yml on pushes to main that touch docs-site/** or the workflow. The workflow uses actions/configure-pages, actions/jekyll-build-pages with docs-site as the source, actions/upload-pages-artifact, and actions/deploy-pages.
Do not add hosted URLs or screenshots unless they exist. Keep public docs free of credentials and local database contents.