Local, on-device autocomplete for macOS. Typer shows a faint inline suggestion right at your cursor in (almost) any text field — keep typing to follow it, press Tab to take a word, or ` to take the whole thing. Everything runs on your Mac with llama.cpp and a small GGUF model — no cloud, no account, no Apple Developer Program.
🌐 typr.frgmt.xyz · 📓 Changelog · 🛠 Contributing
Status: alpha. Feels good in native and Electron/WebKit apps; terminals and custom-drawn editors still have approximate caret placement. Feedback and PRs welcome.
- Inline ghost-text completions at your caret, streaming word-by-word (first word in well under ~100ms).
- Type-into-the-suggestion — as long as you type what it predicted the ghost just shrinks; it only re-thinks when you diverge.
- Learns your voice locally — it primes the model with how you actually write. Nothing leaves your Mac; clear it any time.
- Per-app context, plus opt-in window-text, clipboard, and topic memory (all on-device).
- Typo correction via the macOS spell checker (off by default).
| Key | Action |
|---|---|
| Tab | Accept the next word |
| ` (backtick) | Accept the whole suggestion |
| Esc | Dismiss |
| (keep typing) | Follow along — matching keystrokes consume the ghost |
- macOS 14 (Sonoma) or later — Apple Silicon recommended
- Xcode Command Line Tools —
xcode-select --install - Homebrew
git clone https://github.com/frgmt0/typer.git
cd typer
./install.shinstall.sh installs llama.cpp, downloads a model, writes a default config, and builds
~/Applications/Typer.app. Then launch it:
open ~/Applications/Typer.appOn first launch, onboarding walks you through permissions and picking a model size.
- Accessibility — required. How Typer reads what you type and inserts suggestions.
- Screen Recording — optional. Only for caret placement in terminals + on-screen context.
Onboarding links you straight to the right pane. After a rebuild you may need to re-grant Accessibility — see stable signing to make the grant stick.
Click the ⌨︎ menu-bar icon for everything: toggle features live, switch model size, see accept-rate stats, clear your learned style, open the config/log, or check for updates.
- Model size — pick Small (fast, runs on any Mac) or Large (higher-quality suggestions, best on 16 GB+ of RAM). Large downloads once, on demand, and switches live — no restart. Change it from the menu dropdown or during onboarding.
Typer builds from source, so updating means pulling the latest and rebuilding. Either:
./update.sh # fast-forward to the latest, rebuild, relaunch…or click the ↻ button in the menu-bar popover — it fetches, tells you how many commits
behind you are, then rebuilds and restarts in the background (progress in
~/Library/Logs/Typer-update.log). It only fast-forwards, so local changes are never
overwritten.
Everything is local — the model runs on your machine and nothing is sent anywhere.
- Secure input is never captured — password fields, the login window,
sudo, password managers: no buffering, learning, logging, or generation. - The log is not a keylogger — by default it records no typed text (only counts/events).
- Your files are yours —
style.txtandstats.jsonlive under~/Library/Application Support/typer/(mode0600); wipe them any time (Menu → Clear Learned Style / Reset All Data).
Hacking on Typer with Claude Code, Cursor, or similar? Paste this to orient your agent fast:
You're contributing to Typer, a local on-device autocomplete app for macOS (Swift/AppKit + SwiftUI front end, a C++ llama.cpp helper, and a Python training pipeline). Get oriented before we change anything:
- Read
README.mdandCONTRIBUTING.md.- Map the architecture: the menu-bar app in
scripts/typer/— start atTyperApp.swift(the coreTyperAppclass) and itsextension TyperAppfiles split by concern (+EventTap,+Completion,+Caret,+Context,+Menu,+Model); the generation helperscripts/llama_server.cpp(llama.cpp over a JSONL stdin/stdout protocol); and the model work intraining/(readtraining/README.md).- Note the flow:
scripts/build.shcompiles the Swift app + C++ server, signs, and installs to~/Applications/Typer.app;./update.shpulls + rebuilds.Then give me a short summary of (a) how a keystroke becomes ghost-text at the caret, (b) how the model is selected and loaded (Small vs Large), and (c) where completion quality is tuned. Ask before editing anything.
PRs welcome — see CONTRIBUTING.md for the build/run flow, project layout, architecture, configuration, and the model-training pipeline.
MIT — see LICENSE. Bring your own model (subject to that model's license).