Kristopher Baker iOS roots · Product systems · AI-assisted workflows
← Aoede

shipped · 2026.06.07 · 2 min read

Aoede Comes to iOS

I thought I was porting an app. It turned out I was extracting one. Aoede runs on iPhone and iPad now, but almost none of the work was the iOS app itself. The whole brain of Aoede, the document model, the playback coordinator, the MLX Kokoro speech stack, lived inside the macOS target, which meant there was no app to share, just a Mac app with everything welded to it. So the first step was pulling all of it into a package, AoedeFeatureKit, that both apps now consume. The iOS app on top of it is deliberately thin: a touch-first library, a compact reader that reuses the same karaoke highlighting and follow-scroll, a glass transport bar, lock-screen controls, and background audio.

Sharing the brain surfaced every place the code quietly assumed it was on a Mac. MLX needs a real Metal GPU, which the iOS Simulator does not have, so launching there aborted instantly; Kokoro is now detected as unsupported on the simulator and the app falls back to Apple's voices. The OpenJTalk dictionary was unpacked by shelling out to /usr/bin/tar, which iOS does not have, so Japanese on device falls back to the Apple-reading G2P and CFStringTokenizer furigana until I write a cross-platform extractor. Memory is tighter too: on iOS, overshooting RAM gets the app killed rather than just enlarging its footprint, so the MLX cache cap scales with the device (roughly a 24th of RAM), and phones under about 6 GB get a gentle caution if they pick Kokoro. Apple speech stays the default everywhere.

It is the same reader and the same highlight, now sharing one codebase across two platforms. The desktop and the phone diverge only where the hardware forces them to.