# Install USB Relay on macOS

> Install USB Relay on an Apple Silicon Mac and keep it running with a LaunchAgent so an attached Stream Deck appears in Buttons as a network surface.

USB Relay lets a Stream Deck plugged into a Mac show up in Buttons as a network surface, even though it isn't physically attached to the machine running Buttons. On macOS, this means installing a signed package and then configuring it to run persistently yourself: the installer doesn't set up autostart for you. Before you begin An Apple Silicon Mac (the current build targets Apple Silicon only) with any Stream Deck hardware you want to relay plugged in. Administrator access, to install the package and grant hardware permissions. A Buttons license above the free tier: adopting a USB Relay surface requires at least an Individual-tier license. Install Download the signed, notarized .pkg installer and run it. Follow the installer through to completion. The package installs the relay binary to /usr/local/bin/ . It does not set up anything to keep it running or start it automatically: that's the next step. Set up automatic login A background service needs an active user session to access USB hardware, so the Mac needs to sign in automatically after a reboot rather than sitting at the login screen. Open System Settings → Users & Groups . Set Automatically log in as to the account this relay should run under. If that option is greyed out, turn off FileVault (Privacy & Security → FileVault) since automatic login is incompatible with it, and make sure the account has a local password rather than only signing in via iCloud. Run it persistently with a LaunchAgent Open Terminal and create the LaunchAgent file: sudo nano /Library/LaunchAgents/com.bitfocus.usb-relay.plist Paste in the following to run in server mode (listens and announces itself so Buttons can discover it automatically): <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.bitfocus.usb-relay</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/bitfocus-buttons-usb-relay-headless</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardErrorPath</key> <string>/tmp/bitfocus-usb.err</string> <key>StandardOutPath</key> <string>/tmp/bitfocus-usb.out</string> </dict> </plist> To connect outbound to a specific Buttons address instead of waiting to be discovered, add -buttonsAddress and the address as extra <string> entries inside ProgramArguments . Save and exit ( Ctrl+O , Enter, then Ctrl+X ). Set correct ownership: sudo chown root:wheel /Library/LaunchAgents/com.bitfocus.usb-relay.plist sudo chmod 644 /Library/LaunchAgents/com.bitfocus.usb-relay.plist Grant hardware access: open System Settings → Privacy & Security → Input Monitoring , select + , press Cmd+Shift+G , type /usr/local/bin/ , select bitfocus-buttons-usb-relay-headless , and make sure its toggle is on. Load it for your current session: launchctl bootstrap gui/$(id -u) /Library/LaunchAgents/com.bitfocus.usb-relay.plist Discover and adopt it in Buttons Once running, open Buttons and follow the normal discovery flow: see Add and attach a surface . The relay itself appears in the discovered list labeled USB Relay ; adopting it also makes any Stream Deck attached to that Mac available to adopt. Maintain it Check it's alive: launchctl list | grep bitfocus ; a number in the first column is its process ID. Watch its logs live: tail -f /tmp/bitfocus-usb.out Restart it without rebooting: launchctl kickstart -k gui/$(id -u)/com.bitfocus.usb-relay ; useful if it stops responding, or after plugging in a new device. Check for a quarantine flag if logs show permission errors despite the process running: xattr -d com.apple.quarantine /usr/local/bin/bitfocus-buttons-usb-relay-headless Remove it sudo launchctl bootout gui/$(id -u) /Library/LaunchAgents/com.bitfocus.usb-relay.plist sudo rm /Library/LaunchAgents/com.bitfocus.usb-relay.plist Then uninstall the package itself the same way you would any other installed software. If Buttons' certificate changes If you replace Buttons' own HTTPS certificate (see Replace the HTTPS certificate ) while a relay is already connected outbound to it, the relay refuses to reconnect until it's told to trust the new one: add -accept-cert-change as an extra argument in the plist once, then remove it again afterward. If you get stuck What you see What to try The relay stops as soon as you log out. Confirm automatic login is set up: a LaunchAgent needs an active session to reach USB hardware, so it won't survive at the login screen. Logs show "Permission Denied" even though the process is running. Check whether macOS quarantined the binary ( xattr -d com.apple.quarantine ... ), and confirm Input Monitoring access is actually granted, not just requested. The relay doesn't appear in Buttons' discovered surfaces. Confirm it's actually running (`launchctl list \ grep bitfocus`) and that both machines are on a network that supports discovery. Its logs ( tail -f /tmp/bitfocus-usb.out ) show an error about being unable to multicast. The relay can't broadcast itself on the network, usually due to a VPN or a corporate network that blocks discovery traffic. Skip discovery entirely by connecting it outbound instead: see the -buttonsAddress step under Run it persistently with a LaunchAgent above. The relay refuses to reconnect after you replaced Buttons' HTTPS certificate. Add -accept-cert-change to the plist's arguments once, reload it, then remove the flag again. USB performance is inconsistent on a headless Mac Mini. An HDMI dummy plug (sometimes sold as a "ghost adapter") can help: it forces macOS to fully initialize its graphics stack, which some setups need for stable USB behavior. Where to go next Add and attach a surface Manage your Buttons license
