This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Prerequisites: Rust (latest stable), Bun
# Install dependencies
bun install
# Run in development mode
bun run tauri dev
# If cmake error on macOS:
CMAKE_POLICY_VERSION_MINIMUM=3.5 bun run tauri dev
# Build for production
bun run tauri build
# Linting and formatting (run before committing)
bun run lint # ESLint for frontend
bun run lint:fix # ESLint with auto-fix
bun run format # Prettier + cargo fmt
bun run format:check # Check formatting without changesModel Setup (Required for Development):
mkdir -p src-tauri/resources/models
curl -o src-tauri/resources/models/silero_vad_v4.onnx https://blob.handy.computer/silero_vad_v4.onnxPhonara is a cross-platform desktop speech-to-text app built with Tauri 2.x (Rust backend + React/TypeScript frontend).
lib.rs- Main entry point, Tauri setup, manager initializationmanagers/- Core business logic:audio.rs- Audio recording and device managementmodel.rs- Model downloading and managementtranscription.rs- Speech-to-text processing pipelinehistory.rs- Transcription history storage
audio_toolkit/- Low-level audio processing:audio/- Device enumeration, recording, resamplingvad/- Voice Activity Detection (Silero VAD)
commands/- Tauri command handlers for frontend communicationshortcut.rs- Global keyboard shortcut handlingsettings.rs- Application settings management
App.tsx- Main component with onboarding flowcomponents/settings/- Settings UI (35+ files)components/model-selector/- Model management interfacecomponents/onboarding/- First-run experiencehooks/useSettings.ts,useModels.ts- State management hooksstores/settingsStore.ts- Zustand store for settingsbindings.ts- Auto-generated Tauri type bindings (via tauri-specta)overlay/- Recording overlay window code
Manager Pattern: Core functionality organized into managers (Audio, Model, Transcription) initialized at startup and managed via Tauri state.
Command-Event Architecture: Frontend -> Backend via Tauri commands; Backend -> Frontend via events.
Pipeline Processing: Audio -> VAD -> Whisper/Parakeet -> Text output -> Clipboard/Paste
State Flow: Zustand -> Tauri Command -> Rust State -> Persistence (tauri-plugin-store)
All user-facing strings must use i18next translations. ESLint enforces this (no hardcoded strings in JSX).
Adding new text:
- Add key to
src/i18n/locales/en/translation.json - Use in component:
const { t } = useTranslation(); t('key.path')
Rust:
- Run
cargo fmtandcargo clippybefore committing - Handle errors explicitly (avoid unwrap in production)
TypeScript/React:
- Strict TypeScript, avoid
anytypes - Functional components with hooks
- Tailwind CSS for styling
- Path aliases:
@/->./src/
Access debug features: Cmd+Shift+D (macOS) or Ctrl+Shift+D (Windows/Linux)
- macOS: Metal acceleration, accessibility permissions required
- Windows: Vulkan acceleration (LLVM 18, Vulkan SDK required for build)
- Linux: OpenBLAS + Vulkan, limited Wayland support, overlay disabled by default
- LLVM 18.1.8 (NOT 22+), set
LIBCLANG_PATH="C:/Program Files/LLVM/bin" - Vulkan SDK, set
VULKAN_SDKenv var - CMake in PATH
- Rust/Cargo in PATH
transcribe-rspinned to=0.2.8(0.2.9 has compatibility issues)