docs/setup-macos.md
On macOS, kanata grabs the keyboard via the
Karabiner-DriverKit-VirtualHIDDevice
driver. The kanata process must run as root because the Karabiner virtual HID
daemon exposes its IPC under /Library/Application Support/org.pqrs/tmp/rootonly/,
which only root can access. This page walks through installing the driver,
granting permissions, and (optionally) registering kanata as a LaunchDaemon so
it starts at boot.
xcode-select --install
The supported driver version is v6.2.0. Kanata's bundled
karabiner-driverkit crate is built against that release's IPC, and pqrs
ships protocol changes between minor versions, so newer driver releases
are not guaranteed to work. Download the .pkg from the
v6.2.0 release page
and run the installer.
Then activate the driver and approve its system extension:
sudo /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager forceActivate
Open System Settings > General > Login Items & Extensions > Driver Extensions
and toggle on the entry for org.pqrs.Karabiner-DriverKit-VirtualHIDDevice.
A reboot may be required if you previously ran deactivate.
Verify the system extension is activated:
sudo launchctl list | grep org.pqrs
If you have Karabiner-Elements installed, you should see
org.pqrs.service.daemon.Karabiner-VirtualHIDDevice-Daemon listed — KE
manages the daemon automatically and you can skip ahead to Step 3.
If you installed only the standalone DriverKit package (no Karabiner-Elements), the daemon will not start on its own. You need to launch it manually or install a LaunchDaemon so it starts at boot.
Quick test (won't survive reboot):
sudo "/Library/Application Support/org.pqrs/Karabiner-DriverKit-VirtualHIDDevice/Applications/Karabiner-VirtualHIDDevice-Daemon.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Daemon" &
Persistent (LaunchDaemon): use the included plist to run the daemon at boot:
sudo cp cfg_samples/karabiner-vhid-daemon.plist \
/Library/LaunchDaemons/org.pqrs.Karabiner-VirtualHIDDevice-Daemon.plist
sudo chown root:wheel \
/Library/LaunchDaemons/org.pqrs.Karabiner-VirtualHIDDevice-Daemon.plist
sudo launchctl bootstrap system \
/Library/LaunchDaemons/org.pqrs.Karabiner-VirtualHIDDevice-Daemon.plist
Verify it started:
sudo launchctl list | grep org.pqrs
You should now see the daemon listed.
Either download a pre-built binary from the
releases page and place it on
your PATH:
chmod +x kanata-macos-arm64
sudo mv kanata-macos-arm64 /usr/local/bin/kanata
Or build from source:
git clone https://github.com/jtroo/kanata && cd kanata
cargo build --release
sudo cp target/release/kanata /usr/local/bin/kanata
kanata needs Input Monitoring permission in
System Settings > Privacy & Security > Input Monitoring to read keyboard
devices. The first time you run kanata as root, macOS will prompt you to add
the binary; you can also pre-add /usr/local/bin/kanata (or wherever you
installed it) by clicking the + button and selecting the binary.
kanata also needs Accessibility permission in
System Settings > Privacy & Security > Accessibility. Installers can ask
macOS to register/show the Accessibility prompt without starting the remap
loop:
/usr/local/bin/kanata --macos-request-permissions || true
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
When launched from Terminal, macOS can report the Terminal/responsible process
as trusted. If kanata does not appear as its own item in Accessibility, add the
installed kanata binary manually with the + button.
Pick a sample config (or your own) and run:
sudo kanata -c cfg_samples/simple.kbd
You should see log lines similar to:
[INFO] kanata v1.x.x starting
[INFO] entering the processing loop
[INFO] init: catching only releases and sending immediately
[INFO] Sleeping for 2s. Please release any keys now.
[INFO] Starting kanata proper
Press a remapped key to confirm the mapping fires. ctrl+space+esc (held
together) cleanly exits kanata.
If kanata aborts immediately with a libc++abi / filesystem_error message,
the on-process diagnostic will print three likely causes: not running as root,
the Karabiner driver not installed/approved, or another process is grabbing
the keyboard exclusively. See the troubleshooting section below.
For login-time / boot-time startup, use the sample LaunchDaemon plist in
cfg_samples/kanata.plist.
Edit the two paths in ProgramArguments to point at your kanata binary and
your config file (the defaults are /usr/local/bin/kanata and
/etc/kanata/kanata.kbd), then install:
sudo cp cfg_samples/kanata.plist /Library/LaunchDaemons/dev.kanata.kanata.plist
sudo chown root:wheel /Library/LaunchDaemons/dev.kanata.kanata.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/dev.kanata.kanata.plist
Verify it is running:
sudo launchctl print system/dev.kanata.kanata
Logs are written to /var/log/kanata.log.
After editing your kanata config (or the plist itself), reload with:
sudo launchctl kickstart -k system/dev.kanata.kanata
Remove the LaunchDaemon (if you installed it):
sudo launchctl bootout system/dev.kanata.kanata
sudo rm /Library/LaunchDaemons/dev.kanata.kanata.plist
If you installed the VHID daemon plist (standalone DriverKit only):
sudo launchctl bootout system/org.pqrs.Karabiner-VirtualHIDDevice-Daemon
sudo rm /Library/LaunchDaemons/org.pqrs.Karabiner-VirtualHIDDevice-Daemon.plist
Remove the kanata binary:
sudo rm /usr/local/bin/kanata
If you are also fully removing the Karabiner driver:
sudo /Applications/.Karabiner-VirtualHIDDevice-Manager.app/Contents/MacOS/Karabiner-VirtualHIDDevice-Manager deactivate
You may then delete the Karabiner-VirtualHIDDevice-Manager.app from
/Applications/.
libc++abi: terminating due to uncaught exception ... filesystem_error
on startup: the three likely causes, in order, are (1) kanata is not running
as root, (2) the Karabiner driver is not installed or its system extension
is not approved, (3) another process is already grabbing the keyboard
exclusively. The kanata process prints this same hint to stderr right before
it aborts.connect_failed asio.system:2 in a loop: the Karabiner VirtualHIDDevice
daemon is not running. This happens when using the standalone DriverKit
package without Karabiner-Elements. See Step 2 above for how to start the
daemon manually or install it as a LaunchDaemon.System Settings > Privacy & Security. If
you reinstalled the binary in place, macOS sometimes invalidates the
permission, so toggle it off and back on.docs/platform-known-issues.adoc for
the full list of known macOS issues.