DEV Community

Cover image for I built GhostType: inline AI text completion for every app on macOS
mk668a
mk668a

Posted on

I built GhostType: inline AI text completion for every app on macOS

Writing the same kind of sentences over and over — meeting replies, status updates, polite refusals — eats a surprising amount of the day. LLMs can finish those sentences for me, but only if I copy-paste into a chat window. By the time I've done that, I could have just typed the thing.

I wanted the LLM to be right where I'm already typing — in Gmail, in Notes, in the X compose box — and I wanted it to run on my own machine. So I built GhostType.

GhostType in Gmail

What it is

GhostType is a menu bar app for macOS 14+ that watches the text field you're typing in, sends the surrounding context to a local LLM server (LM Studio, Ollama, llama.cpp, vLLM — anything OpenAI-compatible), and shows the completion as translucent ghost text right at the cursor. Tab to accept, Esc to dismiss.

You type:  "The meeting covered "
           (pause)
GhostType: "The meeting covered quarterly sales targets and the product roadmap"
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                 Ghost text — press Tab to accept
Enter fullscreen mode Exit fullscreen mode

It works in Safari, Notes, Pages, Mail, and most native macOS apps via the Accessibility API. For apps where AX doesn't expose text (Slack, Discord, some Electron apps), there's a manual trigger (Option + \) that uses an internal keystroke buffer.

Why local-only

Three reasons I didn't want this to be a cloud product:

  1. Privacy. Every email draft, every DM, every half-written idea would otherwise hit someone else's server.
  2. Latency. A round trip to the cloud is fine for chat, not great for completion-as-you-type.
  3. Cost. Local inference on Apple Silicon is free. I run a 3B model on an M2 and it's snappy.

Recommended models that work well at this size:

Model Size Notes
Qwen2.5-Coder-3B ~2 GB Best all-rounder
DeepSeek-Coder-V2-Lite ~2 GB FIM-tuned, high quality
CodeGemma-2B ~1.5 GB Lowest latency

How it works under the hood

  • NSEvent.addGlobalMonitorForEvents — watches keystrokes system-wide (requires Input Monitoring permission)
  • Accessibility API (AXUIElement) — reads the surrounding text from the focused field and writes back the accepted completion (requires Accessibility permission)
  • Overlay NSWindow — a borderless, click-through window draws the ghost text at the caret position
  • OpenAI-compatible client — talks to whatever local server you're running on 127.0.0.1

The whole thing is Swift, about 6 source files of core logic. No background daemons, no kernel extensions.

GhostType on X

Try it

  1. Install LM Studio or Ollama and pull a model
  2. Download GhostType-0.1.0.dmg from the releases page
  3. Grant Input Monitoring + Accessibility permissions
  4. Start typing in any text field

Requirements: macOS 14+, Apple Silicon recommended, 8 GB RAM minimum.

What's next

This is v0.1.0. Stuff I'd like to tackle next:

  • Better context extraction for web inputs (currently falls back to keystroke buffer)
  • Per-app prompt presets (email tone vs. code comments vs. casual chat)
  • Multi-suggestion popup (cycle through alternatives)

Source is on GitHub under PolyForm Noncommercial: github.com/mk668a/GhostType

Happy to hear feedback, especially from people running it with non-default models or unusual local server setups. What would you want it to do that it doesn't?

Top comments (0)