High-Level Architecture
The application follows a three-layer architecture:Technology Stack
Frontend
- React 19: UI framework with concurrent rendering
- TypeScript: Type-safe application code
- Vite: Fast build tool and dev server
- Zustand: Lightweight state management
- TanStack Query: Server state and caching
- Motion: Animation library for transitions
- Shiki: Syntax highlighting for code blocks
- Monaco Editor: Full-featured code editor for labs
- Tailwind CSS: Utility-first styling
Backend
- Tauri 2: Desktop application framework
- Rust: Systems programming language
- SQLite: Local database for course progress
- portable-pty: Terminal emulation
- reqwest: HTTP client for course downloads
- notify: File system watching
- Kokoro TTS: Text-to-speech synthesis (external sidecar)
Project Structure
Core Systems
1. Parser (Frontend)
Location:src/parser/
The parser transforms markdown source files into a structured intermediate representation (IR). It handles:
- Frontmatter extraction (YAML)
- Step segmentation (H1 headings)
- Narration block parsing
- Visualization block parsing (code, data, diagrams, charts, math, previews)
- Trigger extraction and parsing
- Region definition
- Scene sequence building
parse-lesson.ts- Main orchestratorparse-data.ts- Data structure parsingparse-diagram.ts- Diagram parsingparse-seq.ts- Sequential animation DSLbuild-scenes.ts- Scene state computation
2. Presentation Engine (Frontend)
Location:src/presentation/
The presentation engine orchestrates playback of parsed lessons:
- TTS synthesis and audio playback
- Word-level timing synchronization
- Trigger execution at word boundaries
- Scene state transitions
- Animation scheduling
- Playback controls (play, pause, seek, rate)
store.ts- Zustand store for presentation stateuse-playback.ts- Playback orchestration hookevent-scheduler.ts- Trigger schedulingPresentation.tsx- Main presentation componentStage.tsx- Visualization rendering surface
3. Visualization Primitives (Frontend)
Handhold provides four core visualization types:Code (src/code/)
- Syntax highlighting via Shiki
- Line-level diffing and highlighting
- Animated line transitions
- Focus regions
- Annotations
Data Structures (src/data/)
- Array, linked list, tree, graph layouts
- SVG-based rendering
- Pointer animations
- State transitions
Diagrams (src/diagram/)
- Node-edge graph layouts via ELK.js
- Auto-layout with customizable algorithms
- Animated edge drawing
- Label positioning
Previews (src/preview/)
- Live HTML/React rendering in iframe
- On-the-fly JSX compilation (Babel via backend)
- Isolated execution context
4. Text-to-Speech (Backend + Frontend)
Backend:src-tauri/src/tts/
Frontend: src/tts/
TTS synthesis uses the Kokoro neural TTS engine as a sidecar process:
- Backend spawns and manages
kokobinary - Converts narration text to phonemes
- Synthesizes speech with word-level timing
- Returns audio as base64-encoded WAV
- Frontend caches audio per narration block
- Word boundaries sync trigger execution
5. Interactive Labs (Frontend + Backend)
Frontend:src/lab/
Backend: src-tauri/src/container.rs, pty.rs, lsp.rs
Labs provide a full IDE-like environment:
- Monaco Editor: Code editing with syntax highlighting
- LSP Integration: Real-time diagnostics and autocomplete
- PTY: Terminal emulation for commands
- Container Orchestration: Podman/Docker Compose for service dependencies
- File System: Full read/write access to lab workspace
- Test Runner: Integrated test execution and TAP parsing
- Git Integration: Line-level diff visualization
6. Course Management (Backend)
Location:src-tauri/src/course/
Course management handles:
- Course discovery and import
- SQLite-based metadata storage
- Progress tracking (step completion, slide positions)
- Course synchronization from Git repositories
- Manifest parsing
- File serving to frontend
7. Database (Backend)
Location:src-tauri/src/db.rs
SQLite stores:
- Course metadata (title, description, tags, paths)
- User progress (completed steps, slide positions)
- Lab provisioning state
- Settings and preferences
Data Flow
Lesson Playback
- User selects a lesson from the browser
- Backend reads markdown file from disk
- Frontend parser converts markdown to IR
- Presentation engine loads lesson into Zustand store
- TTS synthesizes narration (cached in React Query)
- User presses play
- Audio plays, word boundaries fire triggers
- Triggers update scene state (show/hide/transform blocks)
- Visualization components react to state changes
- Animations execute via Motion library
Lab Execution
- User opens a lab
- Backend provisions workspace directory
- Backend copies scaffold files
- Backend starts language server (if configured)
- Frontend initializes Monaco editor
- User edits code
- LSP provides diagnostics and autocomplete
- User runs tests via terminal or test runner
- Backend executes commands via PTY
- Output streams back to frontend
- Test results parsed and displayed
IPC Communication
All backend functions are exposed as Tauri commands and invoked from the frontend via@tauri-apps/api:
- TTS:
synthesize,export_audio,ensure_tts_ready - File System:
read_file,write_file,create_dir,delete_path - LSP:
lsp_spawn,lsp_send,lsp_kill - PTY:
pty_spawn,pty_write,pty_resize,pty_kill - Container:
compose_up,compose_down,container_logs - Course:
course_list,course_import,course_read_step,step_complete - Git:
git_line_diff,git_status_files
Build Process
-
Development:
bun tauri dev- Vite dev server runs on port 5173
- Tauri watches Rust changes and recompiles
- Frontend hot-reloads on save
-
Production:
bun tauri build- Vite builds optimized frontend bundle
- Rust compiles in release mode with LTO
- Tauri bundles app into platform-native installer
- Sidecar binaries embedded into bundle
- Resources (TTS models, espeak data) packaged
Next Steps
Frontend
Deep dive into React architecture
Backend
Explore Rust backend internals
Parser
Understand the markdown parser
Presentation Engine
Learn how playback works