Selected case study
OpenReader
A local-first AI reader that turns text, PDFs, EPUBs, and articles into synchronized audio on macOS and the web.
- React
- TypeScript
- Tauri
- Rust
- FastAPI
- MLX
- 2
- Desktop + web apps
- Local
- Private AI inference
- Solo
- Built end to end
Challenge
Turn structurally different text, PDF, EPUB, and web content into one responsive read-along experience while running speech generation privately on the reader's device.
Responsibility
Sole designer and engineer. Built the shared reader engine, web and desktop applications, local inference backend, storage integrations, testing systems, packaging, and release pipeline.
Solution
Built a Bun monorepo around a shared React reader package, with Next.js for the web, Tauri and Rust for macOS, and a FastAPI backend using MLX and PyTorch to run Kokoro and Qwen3 locally with direct word timestamps.
Outcome
A live local-first product built independently from end to end, with private offline generation, synchronized word highlighting, project persistence, media export, and shared experiences across macOS and the browser.
One reader engine, two applications
A shared React package powers both the Next.js web application and the Tauri desktop application, keeping reading, generation, playback, and project behavior consistent across surfaces.
Generate in prioritized chunks
Audio generation follows reading priority so playback can begin before an entire book is processed. Cancellation, debouncing, precomputed word mappings, and dual audio elements keep seeking and playback responsive.
Package the runtime, download the models
The desktop application bundles its inference runtime while model weights are installed separately, preserving private local execution without making the distributed application unnecessarily large.