If you’re already using Kanata on macOS, KeyPath works with your existing configuration — no manual copying required.
Quick Start
KeyPath auto-detects your config. On first launch, it checks:
- Running Kanata process (finds config from command-line args)
~/.config/kanata/kanata.kbd~/.config/kanata/config.kbd~/kanata.kbd
When found, click “Use This Config” and you’re done.
What happens:
- KeyPath creates a symlink to your original file (no copying)
- Adds
(include keypath-apps.kbd)to enable KeyPath features - Creates a backup before any changes
- Your config stays in its original location
If your config isn’t detected: Click “Choose Different” to select it manually.
Understanding the Two-File Model
KeyPath uses a two-file configuration model:
~/.config/keypath/
keypath-apps.kbd ← KeyPath owns (regenerated automatically)
keypath.kbd ← You own (preserved, never overwritten)
File Ownership
-
keypath-apps.kbd: Generated by KeyPath for app-specific rules. KeyPath regenerates this file when you use the UI to configure app-specific keymaps. You should not edit this file manually. -
keypath.kbd: Your user-owned configuration file. KeyPath preserves everything you write here. If you use KeyPath’s UI for basic remapping, those rules are written to managed sections (marked with;; === KEYPATH MANAGED ===), but your custom sections are always preserved.
The Include Pattern
Your keypath.kbd should include KeyPath’s generated file at the top:
(include keypath-apps.kbd)
;; Your custom configuration below
(defalias
my-custom-alias (layer-toggle nav)
)
(deflayer base
@my-custom-alias ;; ... rest of your layer
)
Why this works: Kanata processes includes before evaluating the rest of your config, so KeyPath’s app-specific virtual keys are available for your custom rules to reference.
What KeyPath Handles Automatically
When you click “Use This Config”:
- Backup — Creates a timestamped backup before any changes
- Symlink — Links to your original file (no copying)
- Include line — Adds
(include keypath-apps.kbd)if missing - Permissions — Guides you through Input Monitoring and Accessibility
- Driver — Installs Karabiner VirtualHID if needed
- Service — Configures LaunchDaemon for boot-time remapping
Common Patterns & KeyPath Compatibility
Includes
Your existing includes work fine:
(include keypath-apps.kbd)
(include ~/.config/kanata/my-layers.kbd)
(include ~/.config/kanata/my-aliases.kbd)
Important: Place (include keypath-apps.kbd) first so KeyPath’s virtual keys are available.
Device Filtering
KeyPath doesn’t interfere with defcfg device filtering:
(defcfg
process-unmapped-keys yes
device-if "my-keyboard"
)
Your device filters work exactly as they did with standalone Kanata.
Layers & Aliases
All standard Kanata features work:
- Layers:
(deflayer base ...),(deflayer nav ...) - Aliases:
(defalias ...) - Tap-hold:
(tap-hold ...),(tap-hold-release ...) - Tap-dance:
(tap-dance ...) - Macros:
(multi ...) - Variables:
(defvar ...)
TCP Requirements
KeyPath requires TCP to be enabled for:
- Config validation (checks syntax before applying)
- Overlay UI (shows active layer and key mappings)
- Diagnostics (service health checks)
Your config should include TCP settings in defcfg:
(defcfg
process-unmapped-keys yes
tcp-server-port 37001
)
Note: If you don’t specify a port, KeyPath’s setup wizard will add TCP configuration automatically. If you use a custom port, update KeyPath’s service configuration to match.
Command Execution Requirements
KeyPath requires danger-enable-cmd yes for app launching and URL opening features. This is Kanata’s built-in safety gate — disabled by default so random configs from the internet can’t execute arbitrary commands.
(defcfg
process-unmapped-keys yes
tcp-server-port 37001
danger-enable-cmd yes ;; Required for KeyPath app/URL launching
)
Why it’s named “danger”: Kanata’s cmd action can execute any binary with any arguments. The scary name is intentional — it forces you to acknowledge you’re enabling command execution. KeyPath uses this for legitimate app launching via macOS’s open command, but Kanata itself applies no restrictions once enabled.
Script Execution Safety
If you use KeyPath’s script:{path} action URI to run scripts, KeyPath applies several safety layers on top of Kanata’s cmd:
| Safety Measure | Description |
|---|---|
| Disabled by default | Script execution is off until you enable it in Settings |
| File-type whitelist | Only recognized types: .applescript, .scpt, .sh, .bash, .zsh, .py, .rb, .pl, .lua |
| First-run confirmation | Dialog shown before first script execution |
| Audit logging | All script executions logged (last 100 entries) |
| No shell injection | Scripts run via direct interpreter, not shell — no metacharacter attacks |
Note: These protections apply only to KeyPath’s action system. If you write raw (cmd ...) actions in your Kanata config, those bypass KeyPath entirely and run with whatever permissions Kanata has.
Bring Your Own Config (BYOC) — what works and what doesn’t
KeyPath doesn’t parse your Kanata config — it uses TCP and a simulator to understand what’s running. This means your custom rules work perfectly at the engine level, but the UI only shows rules created through KeyPath’s interface.
What KeyPath handles for you (even with BYOC):
- Service management, permissions wizard, driver installation
- Hot reload (config changes detected and applied via TCP)
- Conflict detection, health monitoring, emergency stop (
Ctrl + Space + Esc)
What the UI won’t show:
- Rules written directly in your config file (they still work, just invisible to the UI)
- Complex aliases or macros (use your text editor for these)
- Managed sections (marked
;; === KEYPATH MANAGED ===) are overwritten when you save through the UI — your custom sections are always preserved
Bottom line: Use KeyPath’s UI for new simple rules, keep your hand-written rules in your config file. Both coexist. See ADR-025 for the preservation model.
Troubleshooting
Config Not Loading?
- Check TCP is enabled - KeyPath needs TCP for validation
- Verify include path -
keypath-apps.kbdmust be in the same directory - Check logs -
tail -f /var/log/com.keypath.kanata.stdout.log - Run setup wizard - File → Run Setup Wizard to check for issues
KeyPath Overwrites My Config?
KeyPath only overwrites sections marked with ;; === KEYPATH MANAGED ===. Your custom sections are preserved. If you see unexpected changes:
- Check if you’re editing in a managed section
- Use KeyPath’s UI for new rules, edit your config file for custom rules
- See ADR-025 for the preservation model
TCP Port Conflicts?
If you use a custom TCP port:
- Update your
defcfgto match KeyPath’s service configuration - Or let KeyPath use the default port (37001) and update your config
- Run the setup wizard to synchronize TCP settings
Service Not Starting?
- Check permissions - Run setup wizard to verify Input Monitoring and Accessibility
- Check conflicts - Wizard detects conflicting processes (Karabiner, orphaned Kanata)
- Check logs - View system logs for error messages
- Use Fix button - Wizard’s Fix button resolves most issues automatically
Advanced: Using Symlinks
If you prefer to keep your config in a dotfiles repository or custom location, you can use a symlink:
# Create KeyPath's config directory
mkdir -p ~/.config/keypath
# Create symlink to your existing config
ln -s ~/.config/kanata/my-config.kbd ~/.config/keypath/keypath.kbd
Important: Ensure keypath-apps.kbd is accessible at the symlink location (same directory). KeyPath generates it in ~/.config/keypath/, so if your symlink points elsewhere, the include may fail.
Recommendation: Use KeyPath’s wizard “symlink” option (if available) or copy your config instead of symlinking to avoid path resolution issues.
Next Steps
- Shortcuts Without Reaching — KeyPath’s split-hand detection and per-finger timing make HRM more reliable
- What You Can Build — Concrete examples: Hyper key launcher, window tiling, Vim everywhere
- Launching Apps — Launch apps, open URLs, and tile windows from your Kanata config
- Window Management — App-specific keymaps that switch automatically
- One Key, Multiple Actions — All four tap-hold variants explained
- Alternative Layouts — Colemak, Dvorak, and other keymaps
- Keyboard Layouts — Physical keyboard support
Architecture details
- ADR-027 — Details on the two-file model
- ADR-023 — Why KeyPath doesn’t parse configs
- ADR-025 — How config preservation works
Getting Help
- FAQ — Common questions about KeyPath
- GitHub Issues — Report bugs or ask questions
- Privacy & Permissions — What KeyPath accesses and why
- Kanata documentation — Full Kanata config reference ↗
- Kanata GitHub — Kanata source code and discussions ↗
- Back to Docs