XKey and a modern Vietnamese input method for macOS
Vietnamese Input for macOS - Bộ gõ Tiếng Việt mã nguồn mở cho macOS
At a glance
- What is it?
- XKey is a Swift and SwiftUI Vietnamese input method for macOS that replaces the older input sources with a native implementation supporting Telex, VNI and automatic detection, plus a Debug window, macros, quick typing, spell checking and hotkey translation. The interesting engineering is the two operating modes, CGEvent injection and the experimental Input Method Kit build, and the interesting constraint is that it is distributed as a signed and notarised app through Homebrew.
- Who is it for?
- XKey is a good fit for a Vietnamese speaker on a recent macOS who wants an input method that is actively rebuilt against current releases rather than one that stopped working, because the project ships native Swift code with an auto-updater and a Homebrew cask. It is a poor fit if you need the Input Method Kit path to work reliably, since the README marks that mode as experimental, and a poor fit for users of macOS older than 12.0.
- 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 12 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 October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why another Vietnamese input method exists
The project describes itself as a modern Vietnamese input method for macOS, and the introduction explains the motivation in terms of the alternatives: the existing Vietnamese input methods on macOS often have problems, they are not compatible with the latest macOS versions, they still carry unfixed bugs and are rarely updated or maintained, and they lack modern features and are hard to debug and customise.
XKey was built to address those four points. The response is a native Swift implementation optimised for macOS, compatibility with newer macOS versions starting at 12.0, frequent updates with auto-update, a Debug window to follow the input method's activity in real time, and a set of modern features including Smart Switch, Macro, Quick Typing, spell checking and a personal dictionary.
Two claims in that list are worth checking rather than accepting. The compatibility claim is verifiable in the sense that the app targets 12.0 and newer and is rebuilt often, with three tagged builds of the same version number in the last ten days alone, v1.2.25 built on 20261011, v1.2.25 built on 20261003 and v1.2.25 built on 20261002, with the release tag carrying the build date. A version that is rebuilt every few days is a version that is being tested against current releases continuously.
The privacy claim is also specific: the app runs entirely locally and does not collect user data. That is a meaningful statement for an input method, since keystrokes pass through every such tool, and it is a claim about the app itself rather than about the translation feature, which by design sends text to a third-party provider.
The primary language is Swift, the licence is MIT, the default branch is main, and the last push was on 2026-10-11. The repository is not archived, and there is a Homebrew cask for the app.
The two operating modes, and why the choice matters
XKey runs in one of two modes, and this is the decision that most affects how it behaves in practice.
The default is CGEvent, which uses CGEvent injection. Its stated advantages are that it needs no configuration and works immediately with every app. That is the more dependable choice and the one most people will leave alone.
The alternative is XKeyIM, which uses Input Method Kit and is explicitly marked as experimental. Its stated advantage is that it is smoother in Terminal, Spotlight and the address bar.
That distinction is the interesting one. CGEvent injection synthesises events at the window server level, which means it works anywhere but sits outside the text input system's own awareness of what is being typed. Input Method Kit is the system's own input method framework, where the app participates in text input properly. That is why the IMK path feels better in text fields that macOS handles specially, and why the CGEvent path is the more predictable default.
The repository tree reflects that the two are separate builds. There is a XKey/ directory and a XKeyIM/ directory, an XKeyTests/ directory, and the environment file shows separate switches for each: ENABLE_XKEYIM to enable or disable the XKeyIM build, ENABLE_XKEYIM_BUNDLE to bundle XKeyIM inside XKey.app, and ENABLE_XKEYIM_DMG to create a separate XKeyIM.dmg. The XKeyIM variant can therefore ship either as part of the main app or as its own disk image.
For an end user, the practical upshot is that the default mode works nearly everywhere, and the experimental mode is worth trying if you spend your day in Terminal or Spotlight and find the default mode feels detached from the text field.
The other file at the repository root worth knowing about is QWERTZ_SUPPORT.md, which suggests the key layout is not fixed to QWERTY, and a Vietnamese user on a German or French layout is a real case for an input method.
Typing styles, encodings and the quick typing features
The input side covers five typing styles, and the way they are presented matters because they differ in how much you have to remember.
There is automatic typing style detection, where XKey identifies Telex or VNI as you type. There is Telex, described as the most popular style, where tieengs produces the accented word. There is VNI, the traditional numeric style, where tie61ng does the same job. Then there are two simplified Telex variants: Simple Telex 1, which is Telex without the transformations, and Simple Telex 2, which is Telex plus w for the u and o vowels.
Three encodings are supported. Unicode, UTF-8, is recommended and is the default. TCVN3, also called ABC, exists for compatibility with older software. And VNI Windows exists for compatibility with VNI fonts, which is the older Windows-era approach where the visual glyphs come from the font rather than from the character codes.
Quick Typing is a set of expansions that speed up common consonant sequences rather than accented characters. Quick Telex maps cc to ch, gg to gi, kk to kh, nn to ng, pp to ph, qq to qu and tt to th. Quick Start Consonant maps the initial f to ph, j to gi and w to qu. Quick End Consonant maps the final g to ng, h to nh and k to ch.
That is a different idea from the Telex rules, and it is worth understanding why it exists. Vietnamese typing is dominated by consonant digraphs, and in the traditional ASCII way each digraph needs a modifier key, which is why typing Vietnamese on a plain keyboard was historically slow. Expanding the digraphs directly removes the modifier step for the most common cases at the cost of the initial and final expansions colliding with words that legitimately start or end with those letters, which is presumably why they are separate features rather than always on.
The macro feature is text substitution: you create custom abbreviations, import and export the list as a text file, and optionally auto-capitalise the expansion or append a space after it. The documentation also notes that macros work in English mode as well, which is the practical detail for someone who types both languages in the same application.
Smart Switch, text tools, spell checking and the Debug window
The remaining features are what separate a usable input method from a minimal one.
Smart Switch remembers the language per application and switches automatically when you change apps. It also detects overlay apps such as Spotlight, Raycast and Alfred, which matters because those are exactly the places where a key event can be swallowed by a different UI layer, and a language switch that does not fire inside Spotlight is a common complaint about input methods. There is a separate QWERTZ_SUPPORT.md file, which indicates the layout handling is configurable rather than hardcoded.
The text conversion tools are reachable by configurable hotkey and cover case changes, capitalising everything, lowercasing everything, capitalising the first letter, capitalising each word, converting between the Unicode, TCVN3 and VNI encodings, and stripping diacritics to produce unaccented text.
Spell checking is marked as experimental. It uses a Vietnamese dictionary of about 200KB under a GPL licence, automatically restores what you typed when the spelling is wrong, supports both the newer tone placement and the older tone placement, and offers a personal dictionary so you can add words the general dictionary does not have, with import and export of that personal dictionary.
The Debug window is the feature that makes the rest maintainable. It follows the input method's activity in real time, and for a tool that transforms keystrokes through a rule set, the ability to see what came in and what went out is what turns a bug report from a guess into a diagnosis. The README lists it among the highlights, and the QWERTZ support file suggests the same instinct applied to layout handling.
A note on the dictionary licence is worth making explicitly, because it is the one dependency that does not sit comfortably with the rest of the project. The app is MIT, and the spelling dictionary is around 200KB under a GPL licence. Those are compatible in the sense that a GPL component can be redistributed inside an MIT-licensed work, but the dictionary is a separate work with its own terms, and a redistributor has to account for it.
Hotkey translation, providers and the honest privacy line
The translation feature is the largest subsystem and the one with the clearest external dependency, so it deserves a careful reading.
Two directions are supported with separate hotkeys and independent options. Forward translation takes the selected text, or the whole content of the input field if nothing is selected, and translates it from the source language to the target. The documented shortcut is Command plus Shift plus T by default. The options are whether to replace the original text, whether to copy the result to the clipboard, whether to show it in an overlay popup, and how long the popup stays before hiding itself, with four seconds as the default and zero meaning never hide. All four work independently, and they can be combined, so a forward translation can replace the text, copy it and show the popup at the same time.
Reverse translation goes from the target language back to the source, which the documentation describes as useful for checking meaning or verifying a translation. It has its own defaults, and replacing the original text and copying to the clipboard are off by default while the popup is on, which is the sensible default for a verify-the-translation action.
The popup itself is a glassmorphism overlay that follows light and dark mode, with quick copy, font size increase and decrease, draggable header and edges for resizing, a per-direction auto-hide delay, and a countdown bar showing the time remaining.
On language coverage, there is automatic source language detection, more than 30 common languages including English, Vietnamese, Chinese, Japanese, Korean, French and German, and a custom language option where you enter an ISO 639-1 code to use any language you like.
Three translation providers are listed, each with a stated character. Google Translate is free, multilingual and good quality. Tencent Transmart is free and optimised for Asian languages. Volcano Engine is free and high quality for Chinese and Vietnamese. Each can be enabled or disabled and the priority order can be changed in the settings, and there is automatic fallback: if the preferred provider errors or returns an empty result, the next one is tried automatically, with a clear error message per error type covering network problems and rate limits.
So the privacy claim and the translation feature are in tension, and the documentation is honest enough to show it. The app itself runs locally and collects no user data, and the translation text goes to Google, Tencent or Volcano Engine. That distinction is the one a reader should carry away, and the fallback behaviour is the detail that matters in practice, because a rate-limited provider silently degrading to a different vendor changes both the latency and the data path.
Installing it and building it yourself
For end users there is a Homebrew cask, and the badge in the readme points at the cask formula.
The cask badge in the readme links to formulae.brew.sh/cask/xkey, and the version badge is generated dynamically from a Version.xcconfig file in the repository, which is how the app's marketing version stays in step with the build. The build number is what differs across the tagged releases, since all three recent tags carry the same 1.2.25 version with different build dates.
For anyone building from source, the repository has an XKey.xcodeproj directory, a build_release.sh script, an XKeyTests/ directory, Shared/ and Tools/ directories, and a .env.example that documents the credentials the release pipeline needs. The signing and notarization values are:
[email protected]
APPLE_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
APPLE_TEAM_ID=XXXXXXXXXX
SPARKLE_PRIVATE_KEY=your-private-key-hereThe APP_APP_PASSWORD comment says it is app-specific, generated at appleid.apple.com, and the Sparkle private key is for signing updates, generated with the generate_keys script in a Sparkle checkout. The same file also carries the build switches, each documented in a comment, for codesigning, notarization, DMG creation, the XKeyIM build and variant, Sparkle signing and appcast generation.
The Sparkle reference explains the auto-update path, and the fact that the key is for EdDSA signing says the updates are signed rather than merely served, which is the right way to do it.
The Homebrew route is what most people should use, because a locally built app needs the signing identity and the notarization credentials that only the developer has. The source build is for people who want to change the behaviour, and the .env.example is the checklist for that.
Editorial conclusion
XKey is a good fit for a Vietnamese speaker on a recent macOS who wants an input method that is actively rebuilt against current releases rather than one that stopped working, because the project ships native Swift code with an auto-updater and a Homebrew cask. It is a poor fit if you need the Input Method Kit path to work reliably, since the README marks that mode as experimental, and a poor fit for users of macOS older than 12.0. Before installing, decide which mode you want, because the default CGEvent mode and the experimental XKeyIM mode differ in where they work best, and read the translation provider settings, since translation depends on Google, Tencent or Volcano Engine and the app falls back between them automatically.
Frequently asked questions
What is XKey?
It is a Vietnamese input method for macOS written natively in Swift with a SwiftUI interface, MIT licensed and distributed as a Homebrew cask. It supports Telex, VNI, automatic style detection and two simplified Telex variants, and targets macOS 12.0 and newer.
What is the difference between the CGEvent and XKeyIM modes in XKey?
The default CGEvent mode uses CGEvent injection, needs no configuration and works with every application, while the experimental XKeyIM mode uses Input Method Kit and is described as smoother in Terminal, Spotlight and the address bar.
How do I install XKey on macOS?
With `brew install --cask xkey`, or download a release from the repository. The Homebrew cask formula is linked from the readme, and the app version is published dynamically from the Version.xcconfig file in the repository.
Which translation providers does XKey use?
Google Translate, Tencent Transmart and Volcano Engine, each of which can be enabled or disabled and reordered in the settings. There is automatic fallback to the next provider if the preferred one errors or returns an empty result, with a specific error message per failure type.
Does XKey send my data anywhere?
The app itself runs entirely locally and does not collect user data, but the translation feature sends the selected text to one of the three configured providers. The spell checking dictionary is a separate work of around 200KB under a GPL licence.
What are the Quick Typing features in XKey?
Quick Telex expands cc to ch, gg to gi, kk to kh, nn to ng, pp to ph, qq to qu and tt to th. Quick Start Consonant expands an initial f to ph, j to gi and w to qu, and Quick End Consonant expands a final g to ng, h to nh and k to ch.
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/xmannv-xkey)Was this useful?