HotkeyClash
Find where your keyboard shortcuts clash.
Open-source macOS menu bar utility that scans running apps, config files, and system shortcuts to detect keyboard shortcut conflicts. Master-detail split view shows every clash at a glance.
Features
- Scans running apps' menu bar shortcuts via Accessibility API
- Parses Karabiner-Elements, skhd, Keyboard Maestro, BetterTouchTool, Hammerspoon, and Alfred configs
- Reads macOS system shortcuts (Spotlight, Mission Control, Screenshots, etc.)
- Classifies conflicts as definite (global vs global) or potential (menu vs menu)
- Tells you which shortcut most likely wins, based on where each one hooks the keyboard
- Search by app, action, or key combo, and export the whole report as Markdown
- 720x520 split view: conflict sidebar + detail pane with app icons and source badges
- Zero external dependencies. Pure Apple frameworks.
Install
Homebrew
brew install --cask wunderlandmedia/tap/hotkeyclash
To update later: brew upgrade --cask hotkeyclash.
Download
Grab the latest DMG or ZIP from Releases.
Build from source
git clone https://github.com/Wunderlandmedia/HotkeyClash.git
cd HotkeyClash
xcodebuild -scheme HotkeyClash -configuration Release build
Requires Xcode 16+ and macOS 14+.
Build a release (DMG + ZIP)
# Local build (skip notarization)
./scripts/build-release.sh --skip-notarize
Full notarized release (after one-time Keychain setup)
./scripts/build-release.sh
Artifacts land in build/release/.
What it scans
| Source | Method |
|--------|--------|
| Running apps | Accessibility API (AXMenuBar traversal) |
| Karabiner-Elements | ~/.config/karabiner/karabiner.json |
| skhd | ~/.config/skhd/skhdrc |
| Keyboard Maestro | ~/Library/Application Support/Keyboard Maestro/Keyboard Maestro Macros.plist |
| BetterTouchTool | ~/Library/Application Support/BetterTouchTool/btt_data_store.* (SQLite, read-only) |
| Hammerspoon | ~/.hammerspoon/init.lua (hs.hotkey.bind calls) |
| Alfred | Alfred.alfredpreferences workflow info.plist hotkey triggers |
| macOS system shortcuts | com.apple.symbolichotkeys plist |
Which shortcut actually wins?
A conflict list tells you two things claim the same keys. It does not tell you which one fires. HotkeyClash answers that by working out where each shortcut hooks the keyboard:
| Layer | Who is there | Sees the key | |-------|--------------|--------------| | Driver | Karabiner-Elements | First, before macOS | | Event tap | skhd, BetterTouchTool, Keyboard Maestro | Ahead of the system's own shortcuts | | System | macOS symbolic hotkeys | Before any app-level hotkey | | Global hotkey | Hammerspoon, Alfred | System wide, if nothing above took it | | Menu item | The frontmost app | Last, and only when that app is focused |
The lowest layer usually wins, and that is the one HotkeyClash marks. When two tools sit on the same layer it says so instead of guessing, because the tiebreaker is registration order and no config file on disk records it.
Accessibility permission is required to scan running apps. Config files and system shortcuts work without it.
Planned
- Hammerspoon, Alfred, Raycast parsers
- Real-time "test this shortcut" mode (press a combo, see which app catches it)
- Export conflict report as Markdown
- Auto-rescan on app launch/quit
Star History
Also by Wunderlandmedia
- QuietClip -- Privacy-first clipboard manager for macOS
- WunderType -- AI text correction via keyboard shortcuts
Contributing
Issues and pull requests welcome. Each config file parser is a self-contained method in ConfigFileScanner.swift, making it straightforward to add support for new tools.