Skip to content

Tech Stack

Kenneth LaCroix edited this page Apr 13, 2026 · 1 revision

Tech Stack

MoodHaven Journal is a local-first desktop app built on Tauri v2 (Rust backend) with a React/TypeScript frontend. All user data lives on-device in an encrypted SQLite database.


Core Stack

Layer Technology Notes
Desktop shell Tauri 2 (Rust) Native OS integration
Frontend React 18 + TypeScript Strict mode, no any
Styling TailwindCSS 3 Custom colour tokens
Rich text TipTap ProseMirror-based
State Zustand 4 stores
Database SQLite via rusqlite (bundled) Single file, no server
Encryption AES-256-GCM + PBKDF2 WebCrypto API
Peer identity Ed25519 (ed25519-dalek) Device signing key
Peer discovery mDNS/DNS-SD (mdns-sd) LAN auto-discovery
2FA totp-rs + native CTAP2/HID TOTP + hardware keys
HTTP (Rust) reqwest (json + stream features) WebDAV sync, Oura API
Charts Custom SVG No charting library
Logging tauri-plugin-log + src/lib/services/logger.ts Rotating file (prod), stderr (dev)
Testing Vitest + Testing Library 693 tests
Build Vite 8 + Tauri CLI
Mobile Kotlin + Wear OS Data Layer MessageAPI + ChannelAPI

Browser / PWA Build

The browser build replaces Tauri IPC with IndexedDB via Vite module aliasing:

Module Desktop Browser
Data persistence SQLite (rusqlite) IndexedDB (src/lib/backend/browser.ts)
IPC layer @tauri-apps/api/core invoke src/lib/backend/browser-invoke.ts shim
Tauri-only plugins Native No-op stubs (src/lib/backend/browser-stubs.ts)
HTTP @tauri-apps/plugin-http window.fetch

State Management (Zustand Stores)

Store What it holds
appStore isInitialized, isUnlocked, theme, active view
settingsStore All user preferences (AI, appearance, privacy, journal, health)
booksStore books[], activeBookId
peerSyncStore identity, nearbyPeers, trustedDevices, isDiscovering

Frontend Architecture

Component
    │
    ▼
  Hook  (state + side effects)
    │
    ▼
 Service  (IPC wrappers or pure functions, src/lib/)
    │
    ▼
 Tauri invoke → Rust command handler

Services are thin IPC wrappers or pure utilities — they hold no state. Components use hooks; hooks call services.

Tauri Command Layer

~109 Rust commands registered in src-tauri/src/lib.rs, split across ~21 modules in src-tauri/src/commands/. Each command is:

  1. Defined in src-tauri/src/commands/<module>.rs
  2. Declared in src-tauri/src/commands/mod.rs
  3. Registered in src-tauri/src/lib.rs inside invoke_handler!(...)
  4. Permitted in src-tauri/capabilities/default.json
  5. Wrapped in src/lib/<service>.ts

Full command reference: docs/tauri-commands.md

STT (Speech-to-Text)

  • Engine: whisper.cpp binary as Tauri sidecar
  • Models: on-demand download from Hugging Face to app_data_dir/models/
  • Audio: Web Audio API → 16 kHz mono WAV → sidecar → stdout text → insert at cursor → delete WAV
  • All processing is local — no audio ever leaves the device

View Routing

Navigation is handled by a ViewType enum in appStore. No URL routing library.

ViewType: writing | timeline | onthisday | insights | calendar | settings

Full architecture: docs/architecture.md

Clone this wiki locally