"On Apple Silicon you have four good ears. Pick the default for your voice, keep the others as adapters."
The Non-Negotiable: On-Device
Before comparing engines, the one rule that eliminates most of the market: the engine must run on the machine. A cloud API might be more accurate, but it breaks the two promises that justify Firekeeper — audio staying local and working offline. So every engine below is on-device. The choice among them is about speed, language handling, and packaging, never about "should the audio leave?" The answer to that is always no.
The Four Engines
Engine Nature Role in Firekeeper
------ ------ ------------------
WhisperKit Swift-native, DEFAULT. Handles mixed ko/en.
Core ML large-v3-turbo model.
Apple SpeechAnalyzer macOS 26 API, Fast 2nd engine. No model
OS-managed assets files to ship. Streaming-friendly.
whisper.cpp C/C++, Core ML Kept in reserve; never built.
MLX Whisper Python, MLX Batch 'power mode'; never built.
WhisperKit is the default because it's Swift-native, Core ML-optimized, and — critically — it handles Dad's mixed Korean/English speech. Apple SpeechAnalyzer (macOS 26) is the fast second engine: no model files for the app to manage (macOS downloads the per-locale assets itself), native streaming, but a language trap we'll hit in two lessons. whisper.cpp is the mature alternative the plan kept in reserve; Firekeeper never needed it, and its benchmark CLI, firekeeper-bench, runs WhisperKit directly. MLX Whisper is a Python-based power mode for batch jobs — great for long recordings, wrong for the packaged app, and not built either. Two engines ship; the other two are the map, not the territory.
Default Plus Adapters
Notice the shape: one default plus several adapters. You don't pick a single engine forever; you pick a default for the common case and keep the others swappable behind a common interface. The engine returns text and the language it detected or ran in, so the rest of the app never has to care which of the four produced the words. That interface is the whole subject of the next track — here, just internalize that "which STT engine" is a runtime choice, not a permanent marriage.