Skip to content

malpern/KeyPath

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

KeyPath - Simple Keyboard Remapping for macOS

KeyPath

Remap any key to any other key with a simple, native macOS app

macOS 15+ Swift 6.0 License


๐ŸŽฏ What is KeyPath?

KeyPath is Kanata made easy for macOS.

Kanata is a powerful, cross-platform keyboard remapping engine that can transform your keyboard into exactly what you need. However, using Kanata on macOS requires navigating a maze of technical challenges:

  • Driver installation via command line
  • Permission debugging (TCC, Input Monitoring, Accessibility)
  • Service management (launchd, LaunchDaemons, SMJobBless)
  • Configuration syntax written by hand in Kanata's DSL
  • Code signing & notarization for system-level access
  • Debugging when things go wrong

KeyPath eliminates all of this complexity while preserving Kanata's full power. You get enterprise-grade keyboard remapping with consumer-grade ease of use.

The Problem KeyPath Solves

Before KeyPath: To remap keys on macOS with Kanata, you need to:

  1. Install the Karabiner VirtualHID driver manually
  2. Understand macOS security frameworks (TCC)
  3. Configure launchd services with root privileges
  4. Write Kanata configuration files in a custom syntax
  5. Debug permission issues, service conflicts, and connectivity problems
  6. Handle code signing and notarization for system components

With KeyPath: Click record, press keys, click save. Done.

KeyPath is a complete macOS integration layer that:

  • โœ… Handles all system setup automatically
  • โœ… Provides a beautiful, native SwiftUI interface
  • โœ… Manages permissions, services, and drivers
  • โœ… Generates Kanata configurations from visual recordings
  • โœ… Offers intelligent troubleshooting and diagnostics
  • โœ… Ensures reliable operation with proper system integration

โœจ Why Use KeyPath?

๐ŸŽฏ Dead Simple Workflow

No configuration files, no command line, no technical knowledge required.

  1. Click "Record Input"
  2. Press the key(s) you want to remap
  3. Click "Record Output"
  4. Press what you want it to do
  5. Click Save

Your remapping is active immediatelyโ€”no restart, no manual service management, no file editing.

โšก Instant & Reliable

  • Hot reload - Changes apply instantly via localhost TCP (JSON; default port 37001)
  • System integration - Runs as LaunchDaemon, works at boot time
  • Crash recovery - Automatic service restart and conflict resolution
  • Health monitoring - Real-time status checks and diagnostics

๐Ÿ›ก๏ธ Safe & Secure

  • Emergency stop - Press Ctrl + Space + Esc to immediately disable all remappings
  • Permission wizard - Guided setup handles all macOS security requirements
  • Conflict detection - Automatically detects and resolves system conflicts
  • No telemetry - Works completely offline, no data collection

๐ŸŽจ Native macOS Experience

  • Beautiful SwiftUI interface with Liquid Glass design (macOS 15+)
  • System Settings integration - Follows macOS design patterns
  • Proper signing & notarization - Works with macOS security features
  • Accessibility support - Respects macOS accessibility settings

๐Ÿ”ง Enterprise-Grade Architecture

Built on proven patterns (inspired by Karabiner-Elements):

  • LaunchDaemon architecture - Reliable system-level service management
  • SMAppService-managed daemon - Kanata always runs via SMAppService; KeyPath auto-reinstalls the service if it disappears, so helper restarts never fall back to legacy plists
  • File-based configuration - Simple, debuggable, hot-reloadable
  • Single source of truth - PermissionOracle prevents inconsistent state
  • State-driven wizard - Handles 50+ edge cases automatically

๐Ÿš€ Getting Started

Installation

Option 1: Download Release (Recommended)

  1. Download from the Releases page
  2. Open KeyPath.app
  3. Follow the setup wizard

Option 2: Build from Source

git clone https://github.com/malpern/KeyPath.git
cd KeyPath

# Canonical build (builds, signs, notarizes, deploys to ~/Applications, restarts app)
./build.sh

Troubleshooting builds locally

  • To skip notarization during local iteration: SKIP_NOTARIZE=1 ./build.sh
  • To dry-run signing/notary invocations without touching Apple services: set KP_SIGN_DRY_RUN=1 (used in CI smoke tests too)

The build script automatically:

  • Compiles the Swift package
  • Signs all components with Developer ID
  • Notarizes the app bundle
  • Verifies the bundled SMAppService plist points at kanata-launcher (no legacy launchctl fallback)
  • Installs to ~/Applications/
  • Restarts the app

First Launch

When you first launch KeyPath, the Installation Wizard will guide you through:

  1. Permission Setup - Grants Input Monitoring and Accessibility permissions
  2. Driver Installation - Installs Karabiner VirtualHID driver if needed
  3. Service Configuration - Sets up LaunchDaemon services
  4. System Validation - Verifies everything is working correctly

The wizard handles all technical setup automatically and provides one-click fixes for common issues.

Already Using Kanata?

If you're already using Kanata on macOS, KeyPath can run your existing configuration with minimal changes. See the Migration Guide for details on bringing your own config (BYOC).

Quick path: Copy your config to ~/Library/Application Support/KeyPath/keypath.kbd, add (include keypath-apps.kbd) at the top, and run the setup wizard.

Create Your First Mapping

  1. Record Input: Click the record button next to "Input Key"

    • Press a single key (e.g., Caps Lock)
    • Or a key combo (e.g., Cmd+Space)
    • Or a sequence (e.g., press A, then B, then C)
  2. Record Output: Click the record button next to "Output Key"

    • Press what you want it to do (e.g., Escape)
    • Or a combo (e.g., Cmd+C for copy)
    • Or type multiple keys (e.g., "hello world")
  3. Save: Click Save - your mapping is now active!


๐ŸŽ Features

For Everyone

Feature Description
Flexible Input Record single keys, combos (Cmd+C), or sequences (Aโ†’Bโ†’C)
Flexible Output Map to single keys, combos, or entire phrases
Visual Recording See exactly what keys you're pressing in real-time
Keyboard Overlay Live overlay with selectable physical layout and keymap labels (QWERTY/Colemak-DH/etc)
Instant Apply Changes work immediately - no restart needed
Safety Features Emergency stop (Ctrl+Space+Esc) prevents getting locked out
Smart Setup Installation wizard handles all technical setup automatically
Native macOS UI Beautiful SwiftUI interface with Liquid Glass design (macOS 15+)

For Power Users

Feature Description
Tap-Hold (Dual-Role) Keys that do one thing when tapped, another when held (e.g., home-row mods)
Tap-Dance Keys that do different things based on tap count (single, double, triple)
Complex Mappings Chain multiple actions from a single trigger
Hot Reload Edit config files directly, changes apply instantly via TCP (localhost, default 37001)
System Integration Runs as LaunchDaemon at startup, works everywhere
Extensive Logging Debug issues with detailed logs and diagnostics
Full Kanata Power Access to all of Kanata's remapping capabilities
Configuration Access Edit Kanata configs directly if needed
Service Health Dashboard Visual helper/SMAppService/driver status with one-click fixes

๐Ÿ“‹ Common Use Cases

Popular Remappings

  • Caps Lock โ†’ Escape - Essential for Vim users
  • Right Cmd โ†’ Delete - Easier reach for frequent deleters
  • F1-F12 โ†’ Media Keys - Volume, brightness, playback control
  • Broken Key Workaround - Remap a broken key to a working one

Advanced Uses

  • Home Row Mods - Turn home row keys (A, S, D, F) into modifiers when held, letters when tapped
  • Hyper Key - Turn Caps Lock into Cmd+Ctrl+Alt+Shift combo
  • Tap-Dance Caps - Single tap for Escape, double tap for Caps Lock
  • App Launchers - Map key sequences to launch favorite apps
  • Text Snippets - Type your email address with a key combo
  • Gaming - Create custom key combinations for complex moves
  • Workflows - Map one key to perform multiple actions in sequence

๐Ÿ—๏ธ Architecture & Technical Details

What Makes KeyPath Different

KeyPath isn't just a wrapper around Kanataโ€”it's a complete macOS integration layer that solves real problems:

1. Intelligent Permission Management

  • PermissionOracle - Single source of truth for all permission detection
  • Handles macOS TCC (Transparency, Consent, Control) complexity
  • Detects permission issues before they cause problems
  • Provides one-click fixes for common permission problems

2. Automated System Setup

  • Installs and manages Karabiner VirtualHID driver
  • Handles code signing and notarization for all components
  • Manages LaunchDaemon services and lifecycle
  • Resolves conflicts with other keyboard remappers automatically

3. Visual Configuration Generation

  • Converts visual key recordings into valid Kanata configuration
  • Handles complex modifier combinations and sequences
  • Generates optimized Kanata configs automatically
  • No need to learn Kanata's configuration syntax

4. Reliable Service Management

  • LaunchDaemon architecture ensures remappings work at boot time
  • Automatic crash recovery and conflict resolution
  • Health monitoring with real-time status checks
  • Hot reload via TCP for instant configuration updates
  • Localhost-only TCP (port 37001); Kanata's TCP server currently has no authโ€”future releases may add token-based TCP authentication
  • SMAppService-managed Kanata daemon with a packaged launcher guarantees absolute config paths and Login Items approval flow

5. Comprehensive Diagnostics

  • Built-in system state detection
  • Automatic log analysis and error interpretation
  • Visual permission status with fix suggestions
  • Real-time service health monitoring

Technical Stack

  • Swift 6.0 - Modern Swift concurrency (async/await, actors)
  • SwiftUI - Native macOS UI with Liquid Glass design
  • Kanata - Cross-platform keyboard remapping engine
  • LaunchDaemon - System-level service management
  • Karabiner VirtualHID - macOS HID driver for system-level remapping

๐Ÿ›ก๏ธ Safety & Security

Emergency Stop

If your keyboard becomes unresponsive, press Ctrl + Space + Esc simultaneously. This immediately disables all remappings and restores normal keyboard functionality.

Permission Requirements

KeyPath needs two macOS permissions to work:

  1. Input Monitoring - To detect key presses
  2. Accessibility - To send remapped keys

The setup wizard guides you through granting these permissions with one-click access to System Settings.

TCP Security

  • IPC runs over localhost TCP (default port 37001); Kanata's TCP server currently ignores authentication messages.
  • Threat model: any local process could trigger reloads/status calls; scope is limited to config reload + diagnostics (no arbitrary code execution).
  • Future: plan to add token-based TCP authentication when upstream Kanata exposes it (mirroring the UDP auth flow).

Kanata binary location (LaunchDaemon)

For stable TCC permissions, LaunchDaemon services use the system-installed kanata binary:

/Library/KeyPath/bin/kanata

The helper keeps this binary updated from the bundled copy when needed and ensures proper ownership/permissions. The bundled binary inside KeyPath.app is not used by LaunchDaemons.

What KeyPath Does NOT Do

  • โŒ No internet connection required (offline by default; optional AI config generation contacts Anthropic if ANTHROPIC_API_KEY is present)
  • โŒ No data collection or telemetry
  • โŒ No modification of system files
  • โŒ No kernel extensions

๐Ÿ”ง Troubleshooting

KeyPath Won't Start?

  1. Check macOS version - Requires macOS 15.0 (Sequoia) or later
  2. Run setup wizard - Go to File โ†’ Run Setup Wizard
  3. Check logs - View system logs: tail -f /var/log/kanata.log

Keys Not Remapping?

  1. Check status indicator - Look for green checkmarks in the app
  2. Verify permissions - Ensure permissions granted in System Settings
  3. Use Fix Issues - Click "Fix Issues" button in the app for automated fixes

Need More Help?

Developer Notes

Xcode 26 beta test runner crash (Swift 6.2)

If you're using Xcode 26.0 beta, swift test can crash with SIGABRT after tests pass. Use the workaround:

./run-tests-workaround.sh

Our main test runners (./test.sh and ./Scripts/run-tests-safe.sh) already include this workaround.


๐Ÿ—๏ธ Requirements

System Requirements

  • macOS 15.0 (Sequoia) or later
  • Apple Silicon or Intel Mac

Dependencies (Handled Automatically)

  • Kanata - The remapping engine (bundled with app)
  • Karabiner VirtualHID Driver - For system-level key events

The setup wizard automatically checks for these and helps you install them if needed.


๐Ÿšซ Uninstallation

Recommended Method

  1. Open KeyPath
  2. Choose File โ†’ Uninstall KeyPathโ€ฆ (you can also open Settings โ†’ Advanced โ†’ Uninstall KeyPathโ€ฆ)
  3. Confirm the admin prompt and let the bundled uninstaller remove LaunchDaemons, helper tools, and the app bundle.

Manual Uninstallation

sudo ./Scripts/uninstall.sh
# or for automation:
sudo ./Scripts/uninstall.sh --assume-yes

This removes:

  • LaunchDaemon services
  • System binaries
  • Configuration files
  • Application bundle

When running outside the repository, the same script is bundled at KeyPath.app/Contents/Resources/uninstall.sh and can be invoked directly.


๐Ÿค Contributing

We welcome contributions! KeyPath is designed to make keyboard remapping accessible to everyone, and contributions help make it better.

Quick Start for Contributors

# Clone the repository
git clone https://github.com/malpern/KeyPath.git
cd KeyPath

# Build and test (development)
swift build
swift test

# Production-like build & deploy (recommended for real testing)
./build.sh
mkdir -p ~/Applications && cp -R dist/KeyPath.app ~/Applications/
osascript -e 'tell application "KeyPath" to quit' || true
open ~/Applications/KeyPath.app

See CONTRIBUTING.md for detailed guidelines, architecture overview, and contribution patterns.


๐Ÿ“š Documentation


๐Ÿ“„ License

MIT License - see LICENSE for details.


๐Ÿงช Tests

  • Unit & integration tests: ./Scripts/run-tests-safe.sh โ€“ configures an isolated module cache (.build-ci/ModuleCache.noindex) so SwiftPM never tries to write to ~/.cache (which can be blocked on shared machines).
  • Full developer suite: ./test.sh โ€“ wraps the safe runner and then executes the higher-level integration scripts.
  • CI-full replicator: CI_INTEGRATION_TESTS=true ./Scripts/archive/run-core-tests.sh โ€“ runs the Unit, Core, and IntegrationTestSuite buckets defined in run-core-tests.sh; by default the CI runs with CI_INTEGRATION_TESTS=false, so set this flag manually (or adjust CI) when you need the deeper installer/privileged coverage to execute alongside unit/core tests.
  • SMAppService sanity check: ./Scripts/verify-kanata-plist.sh โ€“ use before distributing a build (CI runs it against Sources/KeyPath/com.keypath.kanata.plist).

If swift test ever complains about ~/.cache/clang/ModuleCache, just use the safe runner above or pass -Xcc -fmodules-cache-path=$(pwd)/.build/ModuleCache.noindex manually.


๐Ÿ™ Acknowledgments

KeyPath stands on the shoulders of giants:

  • Kanata - The powerful keyboard remapping engine that powers KeyPath
  • Karabiner-Elements - VirtualHID driver and architectural inspiration
  • SwiftUI - For the beautiful, native macOS experience
  • macOS Security Team - For the robust security frameworks that make safe keyboard remapping possible

Made with โค๏ธ for the macOS community

If KeyPath helps you, consider โญ starring the repo!

KeyPath makes Kanata's power accessible to everyoneโ€”no command line required.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •