"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. Zero model
zero-download files. Streaming-friendly.
whisper.cpp C/C++, Core ML Fallback / benchmark harness.
MLX Whisper Python, MLX Optional batch 'power mode'.
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 to manage, native streaming, but a language trap we'll hit in two lessons. whisper.cpp is the mature fallback and the natural home for a CLI benchmark harness. MLX Whisper is a Python-based power mode for batch jobs — great for long recordings, wrong for the packaged app.
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, 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.