DEV Community

Henry Godnick
Henry Godnick

Posted on

What I learned building a system-wide AI writing tool on macOS

I assumed a Mac app that helps you write in any text field would be the easy part. It wasn't. Here's what I learned building DraftKey, an on-device writing assistant for the apps you already use.

Reading text across apps means Accessibility

There's no public API that says "give me the text the user is typing in whatever app is in front." What macOS does have is the Accessibility API, the same layer screen readers like VoiceOver use.

The basic flow looks like this:

  1. Ask for Accessibility permission. The user has to approve your app in System Settings under Privacy & Security, and AXIsProcessTrustedWithOptions is how you check (and prompt).
  2. Create a system-wide element with AXUIElementCreateSystemWide() and ask it for kAXFocusedUIElementAttribute to find the focused text field.
  3. Read attributes like kAXValueAttribute, kAXSelectedTextAttribute, and kAXSelectedTextRangeAttribute to get the text and where the cursor is.
  4. Use parameterized attributes like kAXBoundsForRangeParameterizedAttribute if you want to draw UI near the caret.

With standard Cocoa text views, this works well. The problem is everything else.

Not every editor exposes its text

Support depends entirely on how each app exposes its text, and some don't expose much at all:

  • Editors that draw their own text, like many code editors, terminals, and canvas-based web apps, can give you a focused element with no usable value or selection.
  • Chromium and Electron apps often build a fuller accessibility tree only once they know assistive tech is around, so what you see can vary.
  • Some apps report a value but ignore writes to it, or write it but don't register an undo step.

So I stopped promising "works everywhere." DraftKey works in compatible text fields, has per-app controls so you choose where it runs, and skips secure fields completely. Password fields show up with a secure text field subrole, and you should never touch them.

Writing text back is its own decision. Setting the selected text through Accessibility is clean when an app supports it. The common fallback is going through the pasteboard, which means you're messing with the user's clipboard. Whatever you pick, test it app by app.

The modifier-only shortcut

The rewrite panel opens when you tap Command and Option together and let go. A modifier-only shortcut sounds simple, but you're really watching modifier flag changes and deciding "was that a tap, or was the user holding Command+Option on the way to some other shortcut?" If any other key goes down in between, it isn't a tap. Get that wrong and the panel pops up mid shortcut, which is the fastest way to get uninstalled.

Running the model locally has real costs

I wanted writing help that doesn't send your drafts to a cloud AI service. That part works: after a one-time model download of about 1.12 GB, autocomplete and rewriting run offline. The internet is only needed for the download, license activation, and update checks.

But local has tradeoffs you should be upfront about:

  • RAM. The AI features need at least 8 GB of memory, since the model shares it with everything else that's open.
  • The download. A 1.12 GB download on first launch is friction. I made it a separate step with clear messaging instead of hiding it in the app bundle.
  • Speed. Autocomplete has a tight latency budget. If a suggestion shows up after the user already typed the next word, it's noise.
  • Hardware. Apple Silicon makes this practical. That's why DraftKey requires an Apple Silicon Mac on macOS 14 or later.

The upside: it works on a plane, and your draft emails stay on your Mac.

Review before insert, every time

The design decision I'm most sure about: a rewrite never replaces your text directly. You type an instruction like "make it shorter," it works on the current paragraph (or your selection if you highlighted something), you see the result, and you choose whether to insert it.

Language models get things wrong sometimes. They drop a detail or change a meaning. A review step costs one keystroke, saves you from sending something you didn't write, and keeps your voice yours.

Everything is a toggle

Autocomplete, rewrites, local clipboard history (Command+Option+V), and six mechanical keyboard sound profiles all toggle independently. Some people only want the sounds, which work with the AI turned off.

Try it

If you're curious, there's a free typing test with the keyboard sounds on getdraftkey.com. No install needed. And if you've built anything on top of the Accessibility API, I'd love to hear which apps gave you the most trouble.

Top comments (0)