Kristopher Baker iOS · Product engineering · Systems and tooling
← Aoede

decision · 2026.06.07 · 1 min read

Switching Kokoro from Core ML to MLX

Aoede's first Kokoro integration ran through FluidAudio and Core ML. They offered the natural on-device path, but the integration crashed on my M5 Mac with every compute option I tried. The GPU reported a Metal JIT error, while CPU and the Neural Engine failed lower in BNNS. The same library worked on older Apple silicon, so the model itself probably did not cause the problem.

I replaced that runtime with an MLX port of Kokoro. MLX runs on the M5 and provides a timestamp for each token, which improved the synchronized word highlight at the same time. It does require the Metal toolchain and a real GPU, so the provider belongs in the app target rather than a package built with plain swift build. The iOS Simulator cannot run it and falls back to Apple speech.

I kept the Core ML work on a branch in case its hardware support changes. For now, MLX fits better because it works on the machines I use and gives the reader more precise timing.