In short
- JustRec makes subtitles with Whisper running on the Mac through WhisperKit, so your voice never leaves your computer.
- We use a compressed Core ML build of Whisper large-v3 turbo of about 626 MB, downloaded once.
- The first load took around three minutes and a lot of temporary disk space, because Core ML specializes the model for your chip; after that it loads in seconds.
- Transcription starts from the microphone track as soon as you stop, in parallel with the video export.
You can run Whisper on a Mac entirely on device: the model weights are open source, and WhisperKit runs them through Core ML on Apple Silicon. That’s how JustRec makes subtitles for every recording without sending a second of audio to anyone. Below: how we set it up, which model we picked, and what surprised us (a 626 MB download, a first load of about three minutes and, once, a full disk).
Why subtitles had to run on the Mac
The promise on our home page is simple: your voice is never sent to an external AI. Our users record client work: a design review with names on screen, a quote explained line by line, a bug in a client’s admin panel. Sending that audio to a transcription API would mean one more company processing their clients’ data, one more line in a privacy notice, and one more thing to explain to a careful client. Keeping the voice on the Mac fits the rest of the product, which is built local-first and keeps shared copies in the EU.
There were practical reasons too:
- No cost per minute. A cloud API charges for every minute of audio. On the Mac, the cost is the user’s electricity.
- Works offline. After the model is downloaded, subtitles work on a train.
- Subtitles before the upload. Transcription can start the moment you press stop, while the video is still exporting.
We wrote a longer, non-technical comparison in on-device vs cloud transcription. This article is the engineering side.
WhisperKit and Core ML
Whisper is OpenAI’s speech recognition model, released with its code and weights under the MIT license. It handles multilingual speech recognition and language identification, which is what we need for subtitles in the language you speak.
To run it well on a Mac you need it in Core ML format, so it can use the Neural Engine and GPU. We use WhisperKit, part of Argmax’s open-source Swift SDK (MIT license). It downloads Core ML builds of Whisper from Hugging Face, caches them locally, and gives you a Swift API for transcription with word timestamps and voice activity detection. It requires macOS 14, below our own macOS 15 minimum.
We looked at Apple’s own SpeechAnalyzer too. It’s promising, but it needs macOS 26, and JustRec supports macOS 15. WhisperKit runs everywhere our app runs.
Choosing the model
Whisper comes in several sizes, and the trade-off is the usual one: bigger models are more accurate and slower. OpenAI’s own table:
| Size | Parameters | Memory needed | Relative speed |
|---|---|---|---|
| tiny | 39 M | about 1 GB | about 10x |
| base | 74 M | about 1 GB | about 7x |
| small | 244 M | about 2 GB | about 4x |
| medium | 769 M | about 5 GB | about 2x |
| large | 1,550 M | about 10 GB | 1x |
| turbo | 809 M | about 6 GB | about 8x |
From the openai/whisper README, checked November 2026. Relative speed compares models with each other, not with a Mac.
Turbo is the interesting row: close to the large model, at about half the parameters and many times the speed. On a Mac you don’t download these PyTorch checkpoints, though. You download a Core ML conversion, and Argmax publishes many variants. A few from their repository, with the size of each download:
| Variant | Download size | Notes |
|---|---|---|
| small | about 216 MB | Fast and light; less accurate |
| distil-large-v3 | about 594 MB | Distilled large model |
| large-v3-v20240930 (turbo) | about 547 MB or 626 MB | Two compressed builds of large-v3 turbo |
| large-v3 | about 947 MB | The full large model |
Sizes from the argmaxinc/whisperkit-coreml repository on Hugging Face, checked November 2026.
We use large-v3-v20240930_626MB. The v20240930 name is the release where OpenAI added large-v3 turbo, which OpenAI describes as an optimized version of large-v3 with faster transcription and minimal accuracy loss. Its config confirms the trick: the full 32-layer encoder, but only 4 decoder layers.
Why this one? We needed Italian to come out right, not just English, and with this model Italian was correct in our tests. On our development Mac it transcribed about 15 seconds of audio in 3 seconds. It’s also the model Argmax uses in its own README examples.
The cost is size: 626 MB is a lot to ask for an app that is otherwise small. We download it once, into the app’s Application Support folder, and tell the user what’s happening.
The first load: three minutes and a full disk
The download wasn’t the slow part. The first time we loaded the model, it took around three minutes before transcribing anything, and it used a lot of temporary disk space. Once, it filled the disk.
First load
About three minutes before the first word
Plus a lot of temporary disk space. Once, it filled the disk.
The cause
Core ML specialization
The model is compiled for your chip on first load and cached outside the app.
The change
Load it during setup
The model is downloaded and loaded once during onboarding, so the wait comes before the first recording.
WhisperKit’s own documentation explains why. Core ML models are downloaded in a device-agnostic format and have to be “specialized” to your chip before they run. Core ML does this the first time the model loads, and caches the specialized files on disk, outside the app. Apple maintains that cache, and it’s evicted after every OS update or if the model isn’t used for a long time. When the cache is hit, loading takes seconds: about 3 seconds for us.
What we changed after learning this:
- Prepare the model during first-run setup. While you grant permissions and pick a shortcut, JustRec downloads the model and loads it once, then unloads it. The three minutes happen before your first recording, not after it.
- Show progress. The download reports its progress, so a large first download doesn’t look like a frozen app.
- Expect it again after macOS updates. Because the cache can be cleared, the first transcription after an update can be slow again. That’s normal.
- Leave room on disk. If your Mac is nearly full, the specialization step is where you’ll feel it.
From recording to subtitle file
The pipeline is short, and most of the work is in the details.
Audio from the right track. We record the microphone and system audio as separate files (the ScreenCaptureKit article explains why). For subtitles we use the microphone alone, or system audio if there’s no microphone. That means no notification sounds or video soundtracks confusing the model, and transcription can start right away instead of waiting for the exported MP4.
16 kHz mono. Whisper expects 16 kHz mono audio. We read the track with an AVAssetReaderAudioMixOutput that converts as it reads. If a recording has several microphone pieces (you switched microphones halfway), they’re placed at their real start times and any gap is filled with silence, so timestamps stay aligned with the video.
let options = DecodingOptions(
language: code, // nil means "detect"
detectLanguage: code == nil,
skipSpecialTokens: true,
wordTimestamps: true,
chunkingStrategy: .vad // split on voice activity
)
let results = try await pipe.transcribe(audioArray: samples, decodeOptions: options)
Word timestamps into readable cues. Whisper’s segments are often too long for a subtitle. We ask for word timestamps and rebuild the cues ourselves: at most 84 characters and 6 seconds per cue, a break after a full stop or a question mark once a line has some length, and two lines balanced by length. Overlapping cues are trimmed so two never show at once.
Two files next to the video. The result is saved as SRT and VTT beside the MP4 in your library. When you share, the VTT goes up with the video; if subtitles finish after the upload, they’re added to the link when ready. The first words also become the suggested title for the video.
If you want to do the same for your own recordings with any tool, our guide on adding subtitles to a screen recording on Mac walks through the options.
Language detection
In Settings, subtitles can be set to automatic, Italian or English. On automatic, Whisper identifies the language before transcribing, and we log what it detected. It works for the languages JustRec supports, including English, Italian, Spanish, French, German and Portuguese, which matters for agencies that work across borders.
Automatic detection has the usual weak spots: very short recordings, recordings that start with silence, or someone switching languages halfway. If you always speak the same language, set it by hand and the guess disappears.
What we’d tell another developer
Shipping Whisper in a Mac app
- Pick the model on your users’ languages, not on English benchmarks.
- Budget for the first load: download, then Core ML specialization, then the real work.
- Do that first load during onboarding, with visible progress.
- Transcribe the cleanest audio track you have, not the final mix.
- Build your own cues from word timestamps; raw segments read badly.
- Test with low disk space and after a macOS update.
What’s next
Translated subtitles are planned: the transcription stays on the Mac, and the translation would too. We’re also watching Apple’s SpeechAnalyzer for the day our minimum macOS allows it.
For why subtitles matter to the people watching, see why subtitles get your videos watched on mute. For everything else the app does, the features list has it in one place.
Sources
- OpenAI Whisper on GitHub: model sizes, parameters, memory and relative speed, turbo, MIT license, checked November 2026.
- OpenAI Whisper changelog: release v20240930 adds the large-v3-turbo model, checked November 2026.
- Argmax OSS Swift (WhisperKit) on GitHub: requirements, model downloads, MIT license, checked November 2026.
- WhisperKit configuration source, prewarm and Core ML specialization, checked November 2026.
- Argmax WhisperKit Core ML models on Hugging Face: variant names and sizes, checked November 2026.
- Model config of openai_whisper-large-v3-v20240930_626MB: 32 encoder layers, 4 decoder layers, checked November 2026.
- Apple Developer: SpeechAnalyzer (macOS 26.0), checked November 2026.
Frequently asked questions
Can you run Whisper on a Mac without the cloud?
Yes. Whisper's weights are open source under the MIT license, and libraries such as WhisperKit convert them to Core ML so they run locally on Apple Silicon. After the model is downloaded once, transcription needs no internet connection.
How big is the Whisper model?
It depends on the variant. Among Argmax's Core ML builds, small is about 216 MB and the full large-v3 about 947 MB. JustRec uses a compressed large-v3 turbo build of about 626 MB.
Why is the first Whisper load so slow on a Mac?
Core ML specializes the model for your specific chip the first time it's loaded and caches the result on disk. With our model that took around three minutes. Later loads hit the cache and take a few seconds, until a macOS update clears it.
Does Whisper detect the language automatically?
Yes, Whisper can identify the spoken language before transcribing. If you always speak one language, setting it by hand avoids the occasional wrong guess on short or mixed-language recordings.
Does JustRec send my voice to an AI service?
No. Subtitles are generated on your Mac by a speech-to-text model that runs locally. Only the subtitle file is uploaded with the video when you share it.



