构建需 JDK 17、Gradle 8.10.2 与 Android SDK Platform 34,版本不匹配会失败;非拉丁文字(ru/el/uk/bg/mk/he)需单独下载语言包才能滑动解码;自建语言包脚本需先 pip install wordfreq。

CleverKeys
tribixbiteGPL-3.0活跃维护面向重度用户的纯本地 Android 输入法,内置无限剪贴板历史搜索与标签、待办、自研滑行输入和可配置纠错,数据不出设备。
Local-only Android keyboard for power users. Unlimited clipboard history w/search & tags, todos, in-house swipe engine, configurable autocorrect, diy themes, TrackPoint cursor nav, 8 subkeys per key, offline gif support, 0 non-native deps.
git clone https://github.com/tribixbite/CleverKeys
# 用 Android Studio 打开,或按 README 要求配置 JDK 17、Gradle 8.10.2、compileSdk 34 后构建运行 Android 7.0(API 24)及以上的手机;README 未说明具体 CPU/GPU 或内存要求。
本地纯离线的 Android 键盘,把滑动输入、无限剪贴板和深度自定义都做进一个应用
面向重度用户的纯本地 Android 输入法,内置无限剪贴板历史搜索与标签、待办、自研滑行输入和可配置纠错,数据不出设备。
核心能力
- 用设备端 CTC 模型做滑动输入,支持 20 种语言
- 剪贴板无限历史,支持置顶、待办、标签和正则搜索
- 每键 8 个方向共 208 个短滑手势,可映射编辑与导航命令
- 35+ 主题与 DIY 主题创建器,XML 自定义布局
- 零联网权限,全部推理与数据留在设备上
容易踩的坑
- dev-fcf2375CleverKeys Dev Build (fcf2375)pre-release最新正式版2026-11-09 · 2026-11-09 20:09 UTC
CleverKeys Android APK - Development Build
Commit: fcf2375edd9e3b18c9dba7a877097136732191da Branch: main Date: 2026-11-09T15:06:29-05:00
Downloads (per-ABI)
APK Device arm64 Most modern phones (2017+) armv7 Older 32-bit phones x86_64 Emulators, Chromebooks universal All devices Installation
- Download the APK matching your device
- Enable "Unknown sources" in Android settings
- Install and activate in Language & Input settings
- dev-a300131CleverKeys Dev Build (a300131)pre-release2026-11-09 · 2026-11-09 17:50 UTC
查看更新说明
CleverKeys Android APK - Development Build
Commit: a300131c0aae3ca9c5824f2056acee57135c09cb Branch: main Date: 2026-11-09T12:43:09-05:00
Downloads (per-ABI)
APK Device arm64 Most modern phones (2017+) armv7 Older 32-bit phones x86_64 Emulators, Chromebooks universal All devices Installation
- Download the APK matching your device
- Enable "Unknown sources" in Android settings
- Install and activate in Language & Input settings
- dev-a5427cdCleverKeys Dev Build (a5427cd)pre-release2026-11-09 · 2026-11-09 15:41 UTC
查看更新说明
CleverKeys Android APK - Development Build
Commit: a5427cd60c7fe8295efe12f5fd5d3469e1eda9ac Branch: main Date: 2026-11-09T10:38:12-05:00
Downloads (per-ABI)
APK Device arm64 Most modern phones (2017+) armv7 Older 32-bit phones x86_64 Emulators, Chromebooks universal All devices Installation
- Download the APK matching your device
- Enable "Unknown sources" in Android settings
- Install and activate in Language & Input settings
- dev-116ba9eCleverKeys Dev Build (116ba9e)pre-release2026-11-09 · 2026-11-09 09:10 UTC
查看更新说明
CleverKeys Android APK - Development Build
Commit: 116ba9e634eccab037705ab14e1092406d542926 Branch: main Date: 2026-11-09T04:07:13-05:00
Downloads (per-ABI)
APK Device arm64 Most modern phones (2017+) armv7 Older 32-bit phones x86_64 Emulators, Chromebooks universal All devices Installation
- Download the APK matching your device
- Enable "Unknown sources" in Android settings
- Install and activate in Language & Input settings
- dev-9d4003bCleverKeys Dev Build (9d4003b)pre-release2026-11-07 · 2026-11-07 08:32 UTC
查看更新说明
CleverKeys Android APK - Development Build
Commit: 9d4003b3f2b686af9738ccbf6a3fd1872bb57d56 Branch: main Date: 2026-11-07T03:29:47-05:00
Downloads (per-ABI)
APK Device arm64 Most modern phones (2017+) armv7 Older 32-bit phones x86_64 Emulators, Chromebooks universal All devices Installation
- Download the APK matching your device
- Enable "Unknown sources" in Android settings
- Install and activate in Language & Input settings
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
CleverKeys
🗺️ Project Overview
CleverKeys is a feature-rich open-source keyboard for Android. On-device swipe typing with autocorrect, multi-language hot-swap with per-language dictionaries, unlimited clipboard with pinning/todos/tags/regex search/inline editing, offline GIF packs, opt-in on-device voice input, 241 customizable short-swipe commands, TrackPoint cursor control, 35+ themes with DIY creator — all running 100% on-device with zero internet permissions.
What Makes CleverKeys Unique
Open-Source Gesture Keyboard Comparison
| Feature | CleverKeys | HeliBoard | FUTO | FlorisBoard | AnySoftKeyboard | Urik |
|---|---|---|---|---|---|---|
| Gesture Typing in Termux | ✅ | ⚠️ Corrupted⁴ | ❌ Broken | ⚠️ Disabled | ⚠️ Experimental | ❓ |
| Gesture/Swipe Typing | ✅ Stable | ✅ Stable | ⚠️ Alpha | ⚠️ Disabled⁵ | ⚠️ Experimental | ✅ Geometric¹⁰ |
| Multi-Language Swipe⁹ | ✅ 20 languages | ⚠️ Single | ⚠️ English only | ❌ | ❌ | ✅ Simultaneous |
| Gesture Engine Open Source | ✅ | ❌¹ | ✅² | ✅ | ✅ | ✅ |
| ML Training Code Public | ✅ | N/A | ✅⁶ | N/A³ | N/A³ | N/A¹⁰ |
| Model Size | 2.9MB | Proprietary | 62MB | N/A | N/A | N/A |
| APK Size | ~25MB¹² | ~45MB | ~200MB | ~15MB | ~25MB | ~40MB |
| Clipboard History | ✅ Unlimited | ⚠️ 10min default⁷ | ✅ 25 items | ✅ 20-100 items | ❌ 15s hint only | ✅ Encrypted |
| Short-Swipe Actions⁸ | ✅ 208 gestures | ⚠️ Limited | ❌ | ⚠️ Limited | ⚠️ Limited | ⚠️ Space/Del only¹¹ |
| Per-Key Customization | ✅ 241 commands | ❌ | ❌ | ❌ | ❌ | ✅ |
| Custom Layouts | ✅ XML (8 sublabels) | ✅ JSON | ✅ YAML | ⚠️ JSON (no editor) | ⚠️ Addon packs only | ✅ |
| DIY Theme Creator | ✅ | ✅ | ❌ (16 built-in) | ✅ Snygg v2 | ✅ | ✅ |
| Word Suggestions | ✅ | ✅ | ✅ | ❌ (v0.6 planned) | ✅ | ✅ |
| No Internet Access | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| License | GPL-3.0 | GPL-3.0 | Source-First² | Apache-2.0 | Apache-2.0 | GPL-3.0 |
¹ HeliBoard requires Google's proprietary libjni_latinimegoogle.so library for gesture typing (source)
² FUTO uses "Source First License 1.1" — source-available but restricts commercial use (source)
³ FlorisBoard and AnySoftKeyboard use algorithmic approaches (corner matching, template matching) — no ML training involved
⁴ HeliBoard has a known bug where swipe typing in Termux produces duplicated/corrupted output
⁵ FlorisBoard glide typing is disabled by default and labeled "alpha quality" — must be enabled manually in advanced settings
⁶ FUTO swipe training dataset is public on HuggingFace with training code in their repo
⁷ HeliBoard clipboard retention defaults to 10 minutes but is configurable; items are not persisted across restarts by default
⁸ Short-swipe actions: 8 directions × 26 keys = 208 one-touch gestures for navigation (arrows, home/end), editing (select all, undo, cut/copy/paste), function keys (F1-F12), and more — no long-press menus needed
⁹ Multi-language swipe typing: CleverKeys uses one layout-agnostic CTC model for the languages it serves — dictionaries provide word candidates, not language-specific models. 7 languages bundled (en, es, fr, pt, it, de, sv), 13 downloadable (nl, ru, el, tr, id, ms, tl, sw, uk, bg, mk, he, fa). Primary + secondary language support with automatic best-match selection.
¹⁰ Urik uses a geometric/template path matcher (no ML model, no training code applicable) — German-friendly QWERTZ-native with simultaneous multilingual spell-check. CleverKeys ships a complementary geometric decoder for the languages and scripts its CTC model does not serve, selectable via the Prediction Engine setting — see ROADMAP.md.
¹¹ Urik short-swipe is limited to Space (cursor movement) and Backspace (delete word) — no general short-swipe action mapping system.
¹² CleverKeys-v2.0.0-arm64-v8a.apk measured 25,286,923 bytes (25.3 MB) on the 2026-10-22 local release build; the armeabi-v7a and x86_64 splits are 24.7 MB and 26.5 MB.
Why CleverKeys?
Most keyboard apps do one thing well. CleverKeys does many things well:
- Swipe + autocorrect + multi-language — an on-device CTC decoder evaluates multiple language dictionaries per swipe, with contraction-aware autocorrect
- Clipboard as a productivity tool — not just history, but pinning, todos with status tracking, tags, inline editing, regex search, and media support (images/videos/PDFs)
- Deep customization — 208 short-swipe actions, Android intent launching, custom text macros, per-key gesture mapping, XML layout authoring
- Power user essentials — TrackPoint cursor, selection-delete, backspace undo, terminal key support, offline GIF packs
- Auditable ML — model architecture, training code, and datasets all public at CleverKeys-ML
📱 Works Everywhere — Including Termux
CleverKeys is the only open-source keyboard with reliable swipe typing in Termux. Other keyboards either disable gestures in terminals (FlorisBoard), produce corrupted output (HeliBoard), or don't work (FUTO). Commercial keyboards like Gboard and SwiftKey also disable swipe in Termux.
📲 Install Options
*Recommended — Obtainium pulls directly from GitHub releases, avoiding F-Droid's typical 24-48 hour update delay.
🎨 Extensive Theme Engine
CleverKeys features one of the most powerful keyboard theme engines available:
Built-in Themes (36: 18 classic + 18 decorative)
- CleverKeys Dark — Deep purple with silver accents (default)
- CleverKeys Light — Silver keys with purple accents
- Neon Electric Blue / Hot Pink / Cyberpunk — Vibrant neon aesthetic
- ePaper / ePaper Black — High contrast e-ink styles
- Jungle — Tropical teal theme
- Everforest Light — Soft green nature theme
- Monet (Auto) — Material You dynamic colors
- Dark / Light / Black / Alt Black — Classic options
- And many more...
DIY Theme Creator
Build your own themes on-the-fly with full control over:
- Key Colors — Default, Activated, Locked, Modifier, Special
- Label Colors — Primary, Sub-label, Secondary labels
- Border Colors — Full border customization
- Trail Effects — Swipe trail color and style
✨ Features
🧠 Swipe Typing & Autocorrect
- CleverKeys-trained CTC model (2.9MB) trained from scratch on MIT-licensed real swipe data
- Two selectable swipe engines — CTC (default): the 7 bundled Latin languages on any full a–z Latin layout via a 2.9 MB CleverKeys-trained model scoring 89.3% top-1 on a 2,400-swipe held-out English benchmark, plus 6 non-Latin languages (ru, uk, bg, mk, el, he) on their own per-script encoders, plus any imported Latin pack that is a–z-typeable; and geometric (layout-agnostic, no ML model), used when CTC prerequisites are unavailable — including Turkish, whose dotless
ıhas no a–z spelling - Sub-200ms predictions with XNNPACK hardware acceleration
- Autocorrect with contraction support — "dont" to "don't", "im" to "I'm"
- Full inference control — beam width, length normalization, pruning, early stopping
- Next-word prediction (on by default) — built-in phrase suggestions before you type a letter, with optional personalized learning and tap-to-chain
- Suggestion transparency — long-press any suggestion to see which engine produced it and its full score breakdown; optional per-origin markers
- 100% on-device — works in airplane mode, no cloud anything
Optional continuous multiword swipe: enable it in Swipe Typing settings, then dwell inside the spacebar between words. It defaults off; pending words stop when editor/session ownership changes. See the swipe guide and assignment guide for behavior and limits.
🌍 Multi-Language with Hot-Swap
- 20 swipe languages — 7 bundled, 13 downloadable packs
- Primary + secondary language — both dictionaries are evaluated per swipe
- Instant language switch — toggle between languages without reloading
- Per-language custom dictionaries — add words, adjust frequency weights, disable entries
- Smart contractions — language-aware handling across English, French, and more
🎙️ Voice Input (on device, opt-in)
- Offline dictation — a Voice input key (Extra Keys) or the
voice_inputcommand types what you say; the newest words stay underlined until the model confirms them - Opt-in voice pack — import
voicepack-moonshine-v2-tiny-en.zip(English, Moonshine v2 tiny streaming, MIT, ~45 MB) or the more accuratevoicepack-moonshine-v2-small-en.zip(~142 MB) once from thelangpacksrelease; nothing of the model ships in the APK - Microphone only when you turn it on — the permission is requested only when you enable voice input or import a pack; audio is never stored and never leaves the device
- Safe everywhere — terminals and remote-desktop fields get confirmed words only, appended; password fields refuse voice input
- See the voice input guide
📋 Clipboard System
As an IME, CleverKeys has legitimate clipboard access that other apps don't:
- Unlimited history — configurable by count or storage size, persistent across reboots
- Pinned entries — save important clips with drag-and-drop reordering
- Built-in todo list — track items with active/planned/completed status and tags
- Inline editing — edit any clipboard entry directly in the panel
- Regex search — VSCode-style
.*toggle, glob shorthand, full regex power - Media clipboard — images, videos, PDFs with thumbnail previews
- Tags — organize pinned and todo entries with custom tag labels
- Size filter — filter history by entry size and delete all matching entries after a confirmation
- Clear OS clipboard — an assignable command that clears only Android's current clip; saved history stays (#168)
- Export/Import — JSON (text) or ZIP (full backup with media)
🎮 Offline GIF Panel
- No internet permission — GIF packs imported via file picker, not downloaded
- FTS4 search — find GIFs by keyword with compound word fallback
- Category browsing — 17 emotion categories + recently used
- Community packs — import ZIP packs from Discord or build your own
🎯 208 Short Swipe Actions
Assign custom actions to any key's 8 swipe directions:
- 241 built-in commands — navigation, editing, clipboard, function keys, special chars
- Custom text macros — email addresses, signatures, code snippets, emoji sequences
- Explicit dynamic templates — clipboard, selection, UUID and cursor tokens in per-key or popover assignments; ordinary text stays literal
- Verified apostrophe suffix commands — append exact
'sor'to the last verified word, with suffix-only undo and owned learning replacement - Android intents — launch any app, Termux commands, system settings, maps, browser
- Visual feedback — custom icons displayed as sublabels on keys
- Import/Export — share customizations as JSON profiles
- Subkey popover — hold a text key to open a 3×3 grid of its subkeys, slide and release to type or run one; empty and assigned slots open assign/edit screens
- Minimize —
minimize_barandminimize_fabcommands shrink the keyboard to a strip or a floating button (#175)
🖱️ Cursor & Text Control
- TrackPoint navigation — IBM/Lenovo-style joystick cursor on nav key (hold to activate)
- Selection-Delete — hold backspace + swipe to highlight text, release to delete
- Backspace undo — press backspace after autocorrect to revert to original word
- Arrow keys — full cursor control with shift-select support
🔒 Privacy First
- Zero network permissions — literally cannot phone home
- Microphone only on opt-in — voice input is off by default; the microphone is requested only when you turn it on, and audio is recognised on the device and never stored
- No analytics, telemetry, or cloud sync
- One-switch learning control — "Learn From My Typing" gates ALL on-device learning (phrases, word usage, selection adaptation, swipe traces); turning it off stops recording AND stops using what was learned, with a one-tap forget
- Learned-data manager — browse and delete individual learned phrases and words, per language
- Incognito-field aware — honors apps that request no personalized learning (e.g. browser private tabs)
- Password manager privacy — exclude clipboard from 1Password, Bitwarden, KeePassDX, etc.
- Open source = auditable
⌨️ 100+ Keyboard Layouts
- QWERTY, AZERTY, QWERTZ, Dvorak, Colemak, and programming layouts
- International layouts for 30+ languages
- Full XML customization with 8 sublabels per key
- Ctrl/Meta/Fn keys for Termux; terminal apps are detected automatically, and more can be added by package ID (Settings → Advanced)
🎨 35+ Themes with DIY Creator
- Material You (Monet), Rose Pine, Everforest, Cobalt, ePaper, and more
- Full control: key colors, label colors, borders, swipe trail effects
- Dark and light variants for every theme
🌍 Multi-Language Swipe Typing
CleverKeys supports swipe typing in 20 languages with intelligent multi-language features:
ℹ️ Current swipe-typing scope — The default CTC engine covers three groups:
- the 7 bundled Latin languages (English, French, German, Spanish, Italian, Portuguese, Swedish) on any Latin layout that has all 26 letters (QWERTY, AZERTY, QWERTZ, Dvorak, Colemak, …);
- 6 non-Latin languages via script routing — Russian, Ukrainian, Bulgarian and Macedonian (Cyrillic), Greek, and Hebrew — each on its own layout, alphabet and encoder, after you import that language's pack;
- any imported Latin pack whose vocabulary is a–z-typeable (Dutch, Indonesian, Malay, Tagalog and Swahili all measure 100% projectable).
Turkish is the deliberate exception: dotless
ıhas no a–z spelling, so a quarter of the vocabulary — and a sixth of its thousand most frequent words — would be unswipeable under CTC. Turkish is served by the geometric engine instead, which decodes over the board's real keys. Persian (Arabic script, no per-script CTC encoder) is served by the geometric engine the same way on the Persian PC layout oncelangpack-fa.zipis imported. Geometric remains the automatic fallback when CTC prerequisites are unavailable. Successful decoding still requires a usable dictionary, supported letter geometry and a valid trace. The Prediction Engine setting chooses whether CTC is used. Tap typing remains available independently of swipe support.Evidence tiers, stated honestly. Only English, French, German and Spanish have their own measured accuracy bar. Italian, Portuguese and Swedish are provisional — enabled on the frequency-scale evidence they share with French/German/Spanish, never measured on their own. Russian is validation-tier only. Greek, Ukrainian, Bulgarian, Macedonian, Hebrew and every imported pack have no real-swipe probe at any tier — no accuracy number is quoted for them anywhere, and any figure you see for English/French/German/Spanish does not apply to them.
The QWERTY-only ONNX transformer that used to be the default was removed in v1.6.0 (issue #9 is resolved by that removal: no layout is swipe-disabled any more).
Bundled Languages (7)
Included in the APK — no additional download required. All dictionaries are
built by the one-pass evidence classifier (scripts/build_wordlist.py):
frequency-ranked wordfreq candidates vetted by spellchecker/AOSP-LatinIME
oracles with typo/foreign-word negative filters (see the oracle-tier notes).
| Language | Code | Dictionary Size | Oracle tier |
|---|---|---|---|
| English | en | 98,140 words | A (hunspell + aspell + NLTK + pyspell + AOSP) |
| Spanish | es | 50,000 words | A (aspell + pyspell + AOSP) |
| French | fr | 40,000 words | A (hunspell + aspell + pyspell + AOSP) |
| Portuguese | pt | 40,000 words | B (pyspell + AOSP pt_BR∪pt_PT) |
| Italian | it | 40,000 words | B (pyspell + AOSP) |
| German | de | 40,000 words | A (aspell + pyspell + AOSP) |
| Swedish | sv | 40,000 words | C (AOSP only) |
Downloadable Language Packs (23 packs, 20 languages)
Import via Settings → 🌐 Multi-Language → Import Pack; download prebuilt
zips from the langpacks release
(the same files live in scripts/dictionaries/):
| Language | Code | Dictionary Size | Oracle tier / source |
|---|---|---|---|
| Dutch | nl | 40,000 words | A (hunspell + pyspell + AOSP) |
| Russian | ru | 50,000 words | A (hunspell + pyspell + AOSP) |
| Ukrainian | uk | 50,000 words | D (negatives-only) |
| Greek | el | 39,860 words | C (AOSP only, curated down from 46,306) |
| Bulgarian | bg | 35,027 words | D (negatives-only; wordfreq corpus ceiling) |
| Macedonian | mk | 50,000 words | D (negatives-only) |
| Hebrew | he | 50,000 words | C (AOSP oracle) |
| Persian (experimental) | fa | 50,000 words | Leipzig + wordfreq blend, Lilak oracle (22 % half-space compounds); no native-speaker review yet |
| Turkish | tr | 40,000 words | C (AOSP only) |
| Indonesian | id | 28,637 words | D (negatives-only; corpus ceiling ~31k) |
| Malay | ms | 25,861 words | D (negatives-only; corpus ceiling ~28k) |
| Tagalog | tl | 27,922 words | D (negatives-only; corpus ceiling ~30k) |
| Swahili | sw | 20,000 words | Swwiki — Swahili Wikipedia word list (no wordfreq data) |
Packs for the bundled languages (es fr de it pt sv) plus English corpus
variants (opensubtitles-full / opensubtitles-50k / wordfreq) are also
prebuilt alongside them — 23 zips in total. (The former en-norvig-50k variant
was withdrawn on 2026-09-26: its counts derive from Google Web 1T, which carries
no redistribution grant.)
Data sources & licences. Word lists are adapted from
wordfreq (CC BY-SA 4.0; most packs),
FrequencyWords / OpenSubtitles
(CC BY-SA 4.0; the en-opensubtitles* variants) and
Swwiki (CC BY-SA 3.0 → 4.0;
Swahili), Leipzig Corpora Collection counts (CC BY 4.0; Persian), with the AOSP
LatinIME word lists and Lilak (Apache-2.0) as inclusion oracles; the packs are distributed under GPL-3.0-only. Every zip carries a
NOTICE.txt and license / attribution / source manifest keys; full text
in NOTICE.
Multi-Language Features
Primary + Secondary Language
- Set your primary language for main typing
- Add a secondary language for automatic detection
- Both dictionaries are evaluated simultaneously
- Best prediction selected automatically per swipe
Smart Accent & Punctuation Insertion
- Automatic accent marks for languages that need them (café, naïve, señor)
- Language-aware punctuation (Spanish ¿¡, French « », German „")
- Proper handling of contractions across languages
Per-Language Dictionary Manager
- Separate tabs for each active language
- View word frequencies and dictionary statistics
- Add custom words per language
- Import/export language-specific word lists
Creating Custom Language Packs
You can create dictionaries for any language using the included Python scripts:
# Navigate to scripts directory
cd scripts/
# Install prerequisite
pip install wordfreq
# Option 1: Evidence-classifier build for a configured language (recommended)
python build_wordlist.py --lang fr # report mode: classification + review files
python build_wordlist.py --lang fr --write # regenerate fr_words.txt + CKDT binary
python build_all_languages.py --lang fr # + unigrams + langpack zip
# Option 2: Raw wordfreq build for a language without a LANG_CONFIG entry.
# --input is a WORD LIST, one entry per line (optionally "word<TAB|SPACE|,>frequency");
# raw prose (e.g. a Wikipedia dump) is not tokenized — make a word list first.
python get_wordlist.py --lang xx --output xx_words.txt --count 50000
python build_langpack.py --lang xx --name "MyLang" --input xx_words.txt --use-wordfreq --output langpack-xx.zip
# Option 3: Build from your own word list: one entry per line, either "word",
# "word,frequency", "word<TAB>frequency" or "word frequency" (integer or decimal)
python build_dictionary.py --lang xx --input my_words.csv --output my_lang.bin
python build_langpack.py --lang xx --name "MyLang" --dict my_lang.bin --output langpack-xx.zip \
--license CC-BY-4.0 --attribution "My corpus, (c) Me, CC BY 4.0" --source https://example.org
# (build_langpack.py refuses to build a pack whose data source it cannot name —
# pass --data-source for a known upstream, or --attribution/--license/--source for your own)
# Option 4: Batch build every configured language (all except frozen en)
python build_all_languages.py
Script Details:
build_wordlist.py— One-pass evidence classifier (all configured languages; per-language oracles/bands in itsLANG_CONFIG)build_all_languages.py— Orchestrates classifier → unigrams → langpack per languagebuild_langpack.py— Creates deterministic .zip language packs, with licence metadata +NOTICE.txt(--repackadds them to an existing pack without touching its payload)build_dictionary.py— Builds the CKDT V2 binary dictionary from word listsget_wordlist.py— Extracts top N words from wordfreq for a language
Language packs are simple .zip files containing:
dictionary.bin— CKDT V2 binary dictionary (accent-normalization map + frequency ranks)manifest.json— Metadata (language code, name, version, word count, the model block below, andlicense/attribution/source)NOTICE.txt— Attribution, licence and change note for the pack's third-party word dataunigrams.txt— Top-5k word list for automatic language detectioncontractions.json— Apostrophe/elision mappings (languages that use them)model.onnx— CTC swipe encoder, for the non-Latin scripts only (ru, el, uk, bg, mk, he)
(Older packs may also contain a prefix_boost.bin; the importer still accepts it, but nothing has read it since the neural engine was removed in v1.6.0, and new packs do not include one.)
The six script packs carry their own swipe model. Those languages can only swipe-decode with their pack installed anyway, so shipping the graph in the APK cost every other user ~3 MB they could never reach. The app pins each model's SHA-256 and refuses to load a pack model that is not byte-identical to what it pins, so nothing untrusted is ever handed to the ONNX runtime; a mismatch is treated as "no model" and swipe falls back to the geometric engine.
Pre-built Language Packs:
Download from the langpacks release, or grab them from scripts/dictionaries/ when working from a checkout.
📖 Documentation
- User Guide Wiki — 46-page comprehensive documentation
- Feature Specifications — Technical documentation for developers
- Changelog — Version history and release notes
- Roadmap — Planned features and development path
📚 Tech Stack & Open-source Libraries
- Minimum SDK level 24 (Android 7.0+)
- Kotlin based — 100% Kotlin, zero Java
- ONNX Runtime — Microsoft's cross-platform inference engine
- Kotlin Coroutines — Asynchronous processing
- Flow — Reactive data streams
- Material 3 — Google's latest design system
🔧 Building from Source
Requirements
- Android SDK Platform 34 (compileSdk 34; minSdk 24)
- Gradle 8.10.2 (repository wrapper)
- Kotlin 2.0.0
- JDK 17
Commands
# Clone repository
git clone https://github.com/tribixbite/CleverKeys.git
cd CleverKeys
# Debug build
./scripts/gradle-guard.sh assembleDebug
# Run tests
./scripts/gradle-guard.sh runPureTests runMockTests
# APK location
# build/outputs/apk/debug/CleverKeys-v2.0.0-<abi>.apk
Termux Users
Use the included build script which handles ARM64-specific AAPT2:
./build-on-termux.sh
🧠 The ML Model
CleverKeys decodes swipes on-device with a CTC model:
| Component | Details |
|---|---|
| Architecture | Convolutional/recurrent encoder emitting per-frame character distributions |
| Input | Swipe trajectory (x, y, velocity, acceleration) plus the live key geometry — the model is layout-agnostic |
| Decoding | Pure-JVM Viterbi trie beam over the merged per-language lexicon |
| Format | ONNX (cross-platform, optimized inference) |
| Runtime | ONNX Runtime 1.21.1 with XNNPACK acceleration |
| Total Size | 2.91 MB (encoder only — decoding is on the CPU, in Kotlin) |
A layout-agnostic geometric (SHARK2-style) decoder requires no ML model and is used when CTC prerequisites are unavailable. Dictionary and letter-geometry requirements still apply; Bangla tap layouts do not yet establish Bangla swipe support.
Training code, model architecture, and datasets: CleverKeys-ML
☕ Buy me a coffee
This application is completely free and open source. If you want to support continued development, you can send a donation via the methods below:
triQem2gDXHXweNceTKWGfDfN6AnpCHmjR745LXcbix |
|---|
❤️ Credits & Acknowledgments
Unexpected Keyboard
CleverKeys began as a fork of Unexpected Keyboard by Jules Aguillon (@Julow). The original is an excellent, highly customizable keyboard with support for 100+ layouts.
Our projects have since diverged significantly (~900 commits apart):
- Complete rewrite from Java to Kotlin with coroutines and Flow
- On-device gesture typing (CTC ONNX model + geometric decoder)
- Full clipboard system (unlimited history, pinning, todos, tags, inline editing, regex search, media)
- Offline GIF panel with FTS4 search
- Multi-language simultaneous prediction with per-language dictionary management
- Autocorrect with contraction support
- About 7,000 automated tests: 3,687 pure JVM and 1,675 MockK tests, plus 1,646 instrumented tests run on Android 14–17 (API 34–37) emulators (counts of 2026-10-31)
If you want a lightweight keyboard without gesture typing, we recommend the original Unexpected Keyboard.
Swipe Model Research
- Neural Swipe Typing by @proshian — Initial architecture inspiration
- How We Swipe — Research paper and dataset on swipe behavior
- FUTO Swipe Dataset — Hugging Face dataset
⭐ Star History
📢 Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security: See SECURITY.md
⚖️ License
CleverKeys - Gesture Keyboard for Android
Copyright (C) 2024-2026 tribixbite
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Third-party notices: NOTICE; the licence texts it cites: LICENSES/.
Both are also in the app, under Settings → Help & FAQ → Open-source licenses.
Built with Kotlin, ONNX, and a commitment to privacy. Developed in Termux on Android. 🦝✨