Dictation for developers
Code is a bad thing to dictate. The prose around code — commit messages, PR descriptions, review comments, docs — is a very good one.
Voice typing gets sold to developers as a way to write code without touching the keyboard, and that pitch is why a lot of developers try it once and never open it again. Code really is close to the worst thing you could pick to say out loud. But that is a fact about code, not a fact about dictation, and writing code is not most of what writing software involves.
Count what you produced last week that was made of English rather than syntax. A dozen commit messages, a pull request description explaining a change to somebody who was not in the room, twenty review comments, an incident note written at eleven at night, half a design doc, three long replies in a thread, and the paragraph at the top of a README that everyone reads and nobody wants to write.
All of that is prose about a system you already understand, which is the easiest kind of thing to say and one of the more tedious kinds of thing to type. That is the actual case for a dictation key on a developer’s machine, and it has nothing to do with saying "open paren" out loud.
The trouble with dictating code
It is worth being specific about why code resists the format, because none of these get solved by a better recogniser.
- Punctuation density. A line of real code can be a third punctuation by character count, and speech carries none of it except by naming each mark, which takes longer than typing and leaves you counting brackets afterwards.
- Identifiers that are not words. Speech recognition models how people talk, and useMemo, kAXSelectedTextAttribute and retry_after_seconds are not how people talk. The parts that matter most are also silent: casing, underscores and hyphens have no sound, so even a perfect transcript does not say which of the three you meant.
- Structure you cannot pronounce. Indentation is meaning in Python and YAML and it is meaning to a human reader everywhere else, and nesting depth and the shape of an argument list survive a microphone as nothing.
Underneath those sits the reason it does not improve with practice: when you write code you are usually not thinking in sentences. You are holding a structure — this happens before that, this branch is the error case, this value can be null. Speech is a linear, sentence-shaped channel, and pushing a structure through it costs more than typing the structure directly.
The writing that surrounds the code
Now look at the other pile. The commit message. The pull request description. The review comment that says why this is a problem rather than only that it is. The incident note, the design doc, the reply beginning "the reason we did it that way is", the handover before a holiday, the comment above a function explaining a decision the code cannot show.
Every one of those is the same task in different clothes: you understand something, someone else does not yet, and the gap has to be closed in words. That is explaining, and explaining out loud is a skill everyone already has. Most people can say why they changed something faster and more clearly than they can type it, because typing quietly invites you to trim the reasoning down to whatever fits before you get bored. Prompts to a coding agent are the same shape — intent, constraint, context, in sentences — and voice input for Claude Code covers that setup end to end.
It is also the writing that gets skipped, at a very predictable moment: right at the end, when the work is done and the keyboard has stopped being interesting. Nobody skips the code.
Code by hand, explanation by voice
The workflow this suggests is not "dictate instead of typing". It is a split, and it falls somewhere easy to remember.
- Write the change with your hands, the way you always have.
- Stage it and read the diff, which you were going to do anyway.
- Hold the key and say what changed and why, roughly in the order you would say it to somebody sitting next to you — two or three sentences for a commit, a short paragraph for a pull request.
- Read it back, fix one word, ship it.
What the third step buys is timing rather than typing speed. An explanation is cheapest to produce in the ninety seconds after the change is finished, while the whole thing is still loaded in your head, and that is exactly when you are least willing to start typing again. Which is how "refactor" ends up in the log as a commit message.
Exact Clean for the message, Verbatim for the quote
Spoken sentences carry debris, and Voicecape has two modes for it. The choice matters more for developers than for most people, because developers dictate two quite different kinds of thing.
Exact Clean is the working default. It removes the unambiguous fillers and collapses an accidental repeat of a small set of short function words, and it stops there. Say "Uh, this retries the upload once, then falls back to the queue" and what lands is "This retries the upload once, then falls back to the queue." Say "Um, the the migration has to run before the deploy" and the doubled article goes. Your wording, order and emphasis stay, and the cleanup is rule-based code rather than a language model, so nothing in the path can decide your commit message would read better some other way. The boundaries are listed in what "cleaned, never rewritten" actually removes.
Verbatim is right whenever you are dictating something that will be compared literally rather than read for sense: an error string quoted in a review comment, a config value, a command someone should run. There the engine leaves the words alone and only normalises whitespace. It is a smaller promise, and that is the point, because for a quotation you want no judgement applied at all, however conservative it would have been. Verbatim versus cleaned dictation walks the line between them.
A dictionary of the words your job is made of
A general recogniser knows English. It does not know your dependency list, and that is where dictation most often falls over for technical users specifically. The words you say all day and almost nobody else says include your framework, the four internal services named by somebody in 2021, the two-letter abbreviation for the billing system, and the surname of the colleague in half your review comments. A recogniser has no prior for any of them, so it produces the nearest ordinary English word and you spend the time you saved fixing the same three nouns.
The answer is a personal dictionary, held on the Mac and kept separately per language. Entries are handed to the recogniser as a vocabulary hint before each session, which biases the decoder toward those words without constraining it — adding a service name makes that name likelier, it does not make any other word impossible. Ten or fifteen entries covers a working vocabulary, and they are the terms you were going to correct by hand anyway. Why a general model struggles here is covered in why Mac dictation gets names wrong.
Browsers, Electron and the clipboard path
One practical thing explains a behaviour you meet on day one. Most developer writing happens somewhere that is not a native macOS app: a pull request in Chrome, a ticket in Linear, a message in Slack, a commit message in VS Code.
The straightforward way to put text at a cursor on macOS is to ask the focused element to accept it through the accessibility API, and in a native app that works and lands immediately. In web content it does not, and it fails in the most inconvenient way available: Chromium and WebKit advertise the field as writable, accept the write, return success, and never apply it, because the document lives in another process and the reply only means the message was delivered. An app that trusts that reply reports "inserted" over text that has gone nowhere.
So Voicecape checks whether the caret actually moved before calling a write successful, and in web content it skips that route entirely rather than pay for the check forever. What runs instead is the clipboard: your text goes on, a paste keystroke is sent, and your previous clipboard is put back once the paste has been observed to land — every representation of it, images and rich text included.
Two details follow. The clipboard write is marked local to this Mac, so a sentence you just dictated is not pushed through Universal Clipboard to your other devices on the way into a text field. And if you live in a terminal editor where a stray paste in normal mode would be destructive, an insertion setting stops the ladder early and leaves the text on the clipboard for you to place. Which apps take which path is mapped in typing with your voice in any app.
One route is deliberately absent: typing the text out as synthetic keystrokes, character by character. It demos beautifully, then mangles anything with an input method attached and takes seconds to deliver a paragraph.
The honest limit
None of this makes dictating code a good idea. You will still type the brackets, and a personal dictionary will not turn spoken words into camel case. What changes is the part of the job where you already know exactly what you want to say and the only obstacle is the distance between knowing it and having it written down.
There is a second reason this suits the work. An incident note contains the details of a failure, a design doc contains decisions that are not public yet, and a review comment can quote a customer identifier. Recognition and cleanup both run on the Mac against a model that ships inside the app, so none of that text goes near a transcription service — and the network behaviour is written down rather than asserted, in what Voicecape sends over the network.