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”:

  1. Backup — Creates a timestamped backup before any changes
  2. Symlink — Links to your original file (no copying)
  3. Include line — Adds (include keypath-apps.kbd) if missing
  4. Permissions — Guides you through Input Monitoring and Accessibility
  5. Driver — Installs Karabiner VirtualHID if needed
  6. 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?

  1. Check TCP is enabled - KeyPath needs TCP for validation
  2. Verify include path - keypath-apps.kbd must be in the same directory
  3. Check logs - tail -f /var/log/com.keypath.kanata.stdout.log
  4. 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:

  1. Check if you’re editing in a managed section
  2. Use KeyPath’s UI for new rules, edit your config file for custom rules
  3. See ADR-025 for the preservation model

TCP Port Conflicts?

If you use a custom TCP port:

  1. Update your defcfg to match KeyPath’s service configuration
  2. Or let KeyPath use the default port (37001) and update your config
  3. Run the setup wizard to synchronize TCP settings

Service Not Starting?

  1. Check permissions - Run setup wizard to verify Input Monitoring and Accessibility
  2. Check conflicts - Wizard detects conflicting processes (Karabiner, orphaned Kanata)
  3. Check logs - View system logs for error messages
  4. Use Fix button - Wizard’s Fix button resolves most issues automatically

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

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