English | 简体中文
OpenJoystickDriver is a macOS userspace gamepad driver. Its signed app bundle hosts the controller runtime. The same executable provides a low-level CLI for setup, control, and diagnostics.
Use it when a controller works in OpenJoystickDriver but not in a game, emulator, SDL app, or native macOS app.
Quickstart · Install / Remove · Compatibility · Compatibility Identity · Troubleshooting · Contribute · Star
OpenJoystickDriver normalizes physical controller input into controller outputs that apps can understand. It provides compatibility modes for SDL, Apple GameController, Generic HID, and an experimental Xbox One HID target, with common diagnostics and checks in one repo-controlled workflow.
See docs/user/compatibility.md for current backend, output-mode, and device-support status.
Vendor-specific/raw USB controllers use direct IOUSBHost when macOS permits app ownership.
Apple-entitled exclusive Xbox GIP models use the generated
com.openjoystickdriver.XboxUSBDevice USBDriverKit system extension. The app publishes
consumer-facing virtual controllers with CoreHID on macOS 15+ and the IOKit backend on
macOS 10.15–14. The DEXT never publishes virtual HID devices.
The settings UI uses native SF Symbols and brand-referenced colors to identify Xbox and PlayStation protocol families; no brand image assets are bundled. Xbox and PlayStation marks and names remain the property of Microsoft and Sony Interactive Entertainment, respectively, and this project is not affiliated with or endorsed by either company. See Microsoft Trademark and Brand Guidelines and PlayStation's copyright and trademark notice.
- Drag
OpenJoystickDriver.appto/Applications. - Open
OpenJoystickDriver.app. - Open the menu-bar item to review readiness and connected controllers. Choose
Settings…(⌘,) for Overview, Controllers, Profiles, and Debug. - Grant Input Monitoring and Accessibility to OpenJoystickDriver when macOS asks. Use the matching permission icon in the settings footer to start the native macOS flow. These permissions enable physical controller input and controller output.
- If a profile sends keyboard, mouse, pointer, or scroll events, use the Keyboard & pointer permission icon in the settings footer for its separate access check.
- Connect a supported controller, then choose Open Profiles… to create ordinary assignments and adjust stick/trigger response. Use Controllers… or Refresh to update the menu-bar summary.
Your target app should now see a compatible virtual controller.
OpenJoystickDriver has one app bundle in /Applications:
/Applications/OpenJoystickDriver.appThe main application executable also hosts the in-process runtime. There is no nested helper application or second privacy identity.
Use the installed executable for setup and diagnostics:
| Action | Command |
|---|---|
| Check service status | /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless status |
| Disable Open at Login | /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless app login disable |
To uninstall OpenJoystickDriver completely:
-
Disable the login item with:
/Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless app login disable
-
Quit OpenJoystickDriver.
-
Delete
/Applications/OpenJoystickDriver.app. -
Optional: remove OpenJoystickDriver from Input Monitoring and Accessibility in System Settings.
| What you are trying to run | Recommended | Why |
|---|---|---|
| Steam, PCSX2, and other SDL 2/3 apps | Compatibility + SDL2/3 |
Hardware-verified ASTRO HIDAPI identity with Xbox 360-style input and rumble. |
Native macOS apps using GCController |
Compatibility + Apple GameController |
Targets GameController.framework consumers. |
| Apps that inspect HID descriptors | Compatibility + Generic HID |
Descriptor-driven HID surface. |
| A picky app expecting Xbox One HID | Compatibility + Xbox One HID |
Experimental spoof identity for targeted testing; it is not a general fallback. |
CLI equivalents from the installed app bundle:
/Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless compat set sdl2-3| Symptom | What to do |
|---|---|
| The runtime is disconnected | Launch the installed app, then check --headless status. |
| SDL sees 0 controllers | Ensure Input Monitoring and Accessibility are granted, then restart the host and re-test. |
| XboxUSBDevice installation fails | Entitlement-restricted USB controllers remain unavailable; accessible raw controllers can still use direct IOUSBHost. Rebuild the signed app and run --headless extension enable. |
Useful diagnostics:
./scripts/ojd catalog regenerate --check
./scripts/ojd check profiles
./scripts/ojd test parsers-macos14
./scripts/ojd diagnose backends --seconds 5
./scripts/ojd diagnose gamecontroller --seconds 5
./.build/debug/OpenJoystickDriver --headless diagnose catalog --json
./.build/debug/OpenJoystickDriver --headless diagnose runtime --seconds 300 --json
./.build/debug/OpenJoystickDriver --headless controller state --json
./.build/debug/OpenJoystickDriver --headless controller watch --seconds 10 --interval-ms 16
./.build/debug/OpenJoystickDriver --headless controller packets --limit 50
./.build/debug/OpenJoystickDriver --headless app logs show --stream both --lines 100
./.build/debug/OpenJoystickDriver --headless update check
./scripts/ojd diagnose sdl3 --seconds 10When identical controller models are connected, run controller output list
and pass its opaque selector as --device <id> to input or
controller output. This targets the same runtime device identity used by Input
diagnostics instead of selecting an arbitrary matching VID/PID.
See Application service Runtime Health for soak verdicts, high-water limits, and the foreground-consumer polling leak regression probe. See Application Responsiveness for bounded system-tool execution and shutdown guarantees. See CLI and Application Runtime for the shared runtime boundary.
Installed app bundle commands:
/Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless status
/Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless controller list
/Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless diagnose reportParser, record, and test changes do not require signing:
./scripts/ojd catalog regenerate --check
./scripts/ojd check profiles
./scripts/ojd test parsers-macos14
./scripts/ojd check driverkit
swift buildFor application, generated USB DriverKit, signing, and notarization work, start here:
- Signing assets and Apple Developer portal setup
- scripts/README.md
- CONTRIBUTING.md
- docs/development/architecture.md
Useful contribution areas:
- controller parser and record improvements
- compatibility-layer tests and diagnostics
- documentation for supported devices, compatibility identities, and troubleshooting
- reproducible reports for games, emulators, SDL apps, and native macOS apps
Before opening a PR for parser/record work, run:
./scripts/ojd catalog regenerate --check
./scripts/ojd check profiles
./scripts/ojd test parsers-macos14
swift buildSee CONTRIBUTING.md for repository expectations.
Read these files before editing:
- README.md -- product intent and user workflows.
- scripts/README.md -- repository command interface.
- CONTRIBUTING.md -- PR expectations.
- docs/development/architecture.md -- application, DriverKit, and compatibility boundaries.
- docs/user/compatibility.md -- support status and output-mode behavior.
Minimum checks for parser/record changes:
./scripts/ojd catalog regenerate --check
./scripts/ojd check profiles
./scripts/ojd test parsers-macos14
swift build