Desktop helper to visualize split/ergonomic keyboard layouts (Corne, QWERTZ, Dactyl, Magic) and highlight pressed keys in real time. Built with vanilla HTML/CSS/JS on top of Tauri.
git clone https://github.com/maxistar/keyboard_helper.git
cd keyboard_helper- Node.js (LTS)
- Rust toolchain (
rustuprecommended) - Platform dependencies for Tauri v2: tauri.app/start/prerequisites
The Tauri CLI is a dev dependency — npm install pulls it in automatically.
Install dependencies and launch the Tauri dev window:
npm install
npm run tauri devProduce a packaged release build (bundles Rust + frontend):
npm run tauri buildArtifacts will be written to src-tauri/target/release/ (per-platform bundles such as .app, .dmg, .exe, .msi, or distributable archives). Use the standard Tauri CLI flags for platform-specific targets if you need to cross-compile.
Closing the window hides the app to the system tray instead of quitting. Use the tray menu to restore the window or quit the app.
Releases are cut from master with semantic version tags.
- Version source: keep
package.json,src-tauri/tauri.conf.json, andsrc-tauri/Cargo.tomlon the same semver (e.g.,0.2.0). Update all three before tagging so the JS package, Tauri config, and Rust crate stay aligned. - Trigger: create an annotated tag
vMAJOR.MINOR.PATCHonmasterand push it; CI will build macOS/Windows/Linux bundles and publish a GitHub release with the assets attached. The job should fail if the tag does not match the version in both files. - Steps:
- Bump the version in
package.json,src-tauri/tauri.conf.json, andsrc-tauri/Cargo.toml, commit, and merge tomaster. - Draft release notes (highlights, fixes, platform notes). Keep them short and paste them into the GitHub release description after CI creates it.
- Tag the merge commit (
git tag -a v0.2.0 -m "Release v0.2.0") and push the tag (git push origin v0.2.0). - Watch the release workflow in GitHub Actions; when it finishes, open the generated GitHub release for
v0.2.0, paste the release notes into the description, and publish/save.
- Bump the version in
- Non-tag pushes to
masterstill run the build and upload artifacts to the workflow run but do not create a GitHub release entry.
You can point the app at external layout files and pick a default layout via a user config. The app looks for ~/.keyri.json first and then ~/keyri.json.
- Fields:
defaultLayout: key of the layout to select at startup (must exist inlayouts).layouts: object mapping layout keys to eithertrue(use built-in) or a filesystem path (load external JSON).
- Layout combos (layout-specific): add a
combosarray inside a layout file with entries like{ "key1": { "row": 1, "col": 4 }, "key2": { "row": 1, "col": 5 }, "code": "Enter" }. - Layout file format: JSON with
name, optionalbleLayerSource,keySize(w,h,gapin px),keyPositions(array of{row,col}with optionalw/hoverrides), andkeyLayers.keyLayerscan be an object withdefault,shift, etc., or an array where index 0 is the base layer. Each layer entry is[label, code](or an object withtext/imagefor custom labels). bleLayerSourceis optional and enables BLE-authoritative layer updates for the selected keyboard only. Shape:deviceName: BLE keyboard name to matchserviceUuid: custom GATT service UUIDcharacteristicUuid: custom active-layer characteristic UUIDformat: currentlyint32-le
- References: see built-in layouts for structure (
src/layout_corne.json,src/layout_qwertz.json,src/layout_dactyl.json,src/layout_mac.json,src/layout_magic.json). Copy one, edit, and point your config at the new path. Keep a personal config in~/.keyri.json. - If no config file is found, the app loads all built-in layouts and defaults to QWERTY. External layout paths must be readable from the filesystem; otherwise the app falls back to built-ins.
If the selected layout defines bleLayerSource, the app attempts to connect to that keyboard over BLE and listen for active-layer notifications. When BLE sync is active, the on-screen layer indicator follows the keyboard's reported layer and key highlighting remains independent.
- If BLE sync starts successfully, the app bootstraps the current layer and then updates immediately from notifications.
- If BLE metadata is absent, BLE startup fails, or the BLE feed disconnects, the app falls back to the existing non-BLE behavior.
- BLE sync starts and stops automatically when you switch layouts.