KeyType: on-device tab autocomplete for macOS, built from local Swift packages
An open-source Cotypist with macOS system wide AI autocomplete
At a glance
- What is it?
- KeyType watches the focused text field, predicts a short continuation with a local LLM and offers it as ghost text you accept with Tab. It is a MIT-licensed macOS app aimed at people who want Cotypist-style completion without sending keystrokes to a server.
- Who is it for?
- Adopt KeyType if you are on macOS 14+, want Cotypist-style ghost-text completion under an MIT licence, and are willing to grant accessibility permissions so a local model can read the focused field. Do not adopt it if your typing is concentrated in one editor with its own inline completion, if you work on Windows or Linux, or if you need a documented rollback for a bad insertion.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 32 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What KeyType does that a normal macOS text expander cannot
A text expander matches a trigger string you already typed. KeyType reads the focused text field, hands the surrounding text to a local model, and shows a short predicted continuation at the caret before you type it. The README describes the loop plainly: "It watches the focused text field across any app, predicts a short continuation at the cursor using a local LLM, and offers it as ghost text that you accept with Tab."
The word "any" is doing real work there. Because capture happens through the accessibility layer rather than through a per-app plugin, the same behaviour is meant to apply in Mail, an editor, or a browser field without each app cooperating. That is the whole reason the project exists as a separate utility instead of a library, and it is also the source of most of its fragility.
The audience is narrow and identifiable: macOS users who already use a cotypist-style tool, are willing to run a model on their own machine, and care that keystrokes do not leave the device. If you only want completions inside one editor, the editor already has that.
The pipeline: accessibility capture, a budgeted prompt, constrained decoding
The repository layout is the clearest description of the architecture, and it is more modular than most single-developer macOS apps. Logic lives in local SwiftPM packages under Packages/, while the app target is described as a menu-bar shell.
MacContextCapture handles the accessibility focus, caret position and text-field snapshot. Prompting builds a prompt that the layout calls "sectioned, budgeted", meaning the surrounding context is divided into parts and trimmed to a token allowance rather than passed through whole. ModelRuntime wraps llama.cpp, so inference happens in-process on the local machine. ConstrainedGeneration applies logit masking with trie admissibility and search, which is the mechanism that keeps the model from emitting tokens the completion format cannot accept. CompletionUI renders the inline ghost text, TextInsertion picks between pasteboard and keystroke strategies for putting the accepted text in place, and AppCompatibility holds per-app and per-domain override policy.
Two of those deserve attention. First, the split between pasteboard and keystroke insertion is not cosmetic: the two strategies fail differently across apps, and the existence of both suggests the author hit cases where one did not work. Second, AppCompatibility implies that system-wide behaviour is not uniform in practice; some apps need different treatment, and the project encodes that as policy rather than pretending otherwise.
TokenProfiles reads ACPF profiles and includes an offline builder. That is the part of the design that most constrains what the model can do, and the README does not explain what ACPF stands for or how a profile is produced.
Installing KeyType from the DMG and accepting your first completion
The README gives a four-step install. You download the latest release from the releases page, double-click the downloaded KeyType.dmg, drag the KeyType app into Applications, then open KeyType and complete the onboarding. There is no Homebrew formula or package manager step documented.
The onboarding is where macOS permissions get granted; system-wide text capture depends on accessibility access, and the README does not enumerate which prompts appear. Expect to grant what the onboarding asks for before any ghost text shows up.
Developers build from source instead. The stated requirements are macOS 14+ and a recent version of Xcode:
# Clone and open the workspace
git clone https://github.com/johnbean393/KeyType.git
cd KeyType
open KeyType.xcworkspaceAfter the workspace opens, build and run the KeyType scheme. The README also documents per-package builds, which is the fastest way to work on the logic without launching the whole app:
swift build --package-path Packages/AutocompleteCore
swift test --package-path Packages/PromptingThose two commands compile AutocompleteCore and run the Prompting test suite respectively. If you are touching prompt construction, Prompting is the package with tests the README points at directly. Nothing in the README describes how to load a model into ModelRuntime after a source build, so a from-source run may not give you a working completion out of the box the way the DMG does.
Where KeyType breaks, and when it is the wrong tool
The honest limitation is the one the architecture admits to. Reading the focused text field across arbitrary apps is done through macOS accessibility, and accessibility exposure varies by app and by toolkit. The AppCompatibility package exists precisely because uniform behaviour was not achievable, and the README does not publish the list of apps that need overrides. If your daily work happens in an app that does not expose its text field usefully, KeyType has nothing to read.
Insertion is the second soft spot. TextInsertion carries both pasteboard and keystroke strategies, which means accepted text is placed by simulating input or manipulating the clipboard rather than through a first-party API. Clipboard-based insertion can interfere with whatever you had copied, and keystroke simulation can be swallowed by apps with their own key handling. The README does not document rollback for a bad insertion.
Constrained decoding is a mitigation, not a guarantee. Logit masking with trie admissibility restricts the token space, but the README makes no accuracy claim and publishes no evaluation numbers. The KeyTypeBench-20260603/ and KeyTypeBench-20260607/ directories at the top level suggest benchmarking happened, but the README does not link results, so treat any quality expectation as unverified.
Finally, this is a macOS-only utility. The README states macOS 14+ for development. On Linux or Windows there is no path here at all, and if you want completion in a terminal or over SSH, a local GUI app that reads the focused field is the wrong shape.
KeyType against Cotabby, Cotypist and the editor's own autocomplete
The README positions KeyType as "a MIT-licensed alternative to the closed-source app Cotypist". The meaningful difference is not the feature list, it is where the model runs and what you can inspect. Cotypist is closed source, so its prompt construction, context budget and insertion strategy are not visible to you. In KeyType those are separate packages with names that say what they do.
Cotabby is the other name that comes up in the same conversation, and it appears in the repository topics alongside cotypist. Nothing in the README describes how Cotabby is implemented, so any comparison on that axis would be guesswork; what can be said is that KeyType's distinguishing claim is on-device inference through a llama.cpp wrapper, not a hosted endpoint.
The third alternative is the one already inside your tools. VS Code, Xcode and most editors ship their own inline completion, and those integrations know the document's syntax and project structure in a way a focused-field snapshot cannot. If your typing is concentrated in one editor, the built-in completion is likely better informed and requires no accessibility permissions. KeyType's advantage only appears when you want the same behaviour in apps that have no completion feature of their own.
Maintenance, licensing and what a fork inherits
The repository is not archived, and the last push was on 2026-08-29, which is recent. The release history shows v1.6.0 on 2026-06-27, v1.7.0 on 2026-08-28 and v1.8.0 on 2026-08-29, so the two most recent releases landed within a day of each other after a two-month gap. That pattern is worth knowing before you plan an upgrade cadence: the project does not appear to ship on a fixed schedule.
Upgrade cost is mostly the DMG replacement path plus re-onboarding, since the README documents no settings migration or downgrade procedure. There is no documented rollback if a new release regresses insertion behaviour in an app you rely on, so keeping the previous DMG is the only obvious fallback and the README does not say whether older releases remain downloadable.
Licensing is MIT, with the LICENSE file at the repository root. MIT permits use, modification and redistribution with the licence and copyright notice retained. That matters for anyone embedding the packages rather than shipping the app: the SwiftPM packages under Packages/ are part of the same repository, so the same terms appear to apply, though the README does not state a separate licence for them. If you plan to redistribute a modified build, read LICENSE yourself rather than relying on this summary; nothing here is legal advice.
One practical note for forkers: the ModelRuntime package wraps llama.cpp, and the README does not describe how that dependency is vendored or which version is pinned. That is the first thing to check before assuming a fork will build cleanly later.
Editorial conclusion
Adopt KeyType if you are on macOS 14+, want Cotypist-style ghost-text completion under an MIT licence, and are willing to grant accessibility permissions so a local model can read the focused field. Do not adopt it if your typing is concentrated in one editor with its own inline completion, if you work on Windows or Linux, or if you need a documented rollback for a bad insertion. Before relying on it, verify two things yourself: that the apps you type in most expose their text fields well enough for MacContextCapture to read them, and what the onboarding actually asks you to grant. Then check whether the current release's insertion strategy behaves in those apps, since TextInsertion carries both pasteboard and keystroke paths and the README does not document which one is used where.
Frequently asked questions
Does KeyType work on macOS only?
Yes. The README describes it as a system-wide tab-autocomplete utility for macOS, and development requires macOS 14+. There is no documented build path for Linux or Windows.
How do I install KeyType?
Download the latest release from the releases page, double-click the downloaded KeyType.dmg, drag the KeyType app into Applications, then open it and complete the onboarding. The README lists no package manager install.
Does KeyType send my typing to a server?
The README describes it as on-device, with ModelRuntime acting as a llama.cpp wrapper, so inference runs locally. The README does not describe any network inference path.
Which apps does KeyType work in?
The README says it watches the focused text field across any app, but the AppCompatibility package handles per-app and per-domain overrides, which implies behaviour is not identical everywhere. The README does not publish a compatibility list.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/johnbean393-keytype)