Warning
All compiled 'releases' before 0.5.0-alpha.4 have been swooped due to #23. Please be patient (or compile a private version yourself) for 0.5.0-beta.1. Thanks for your patience.
- Krystian, OJD's core maintainer.
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 virtual controller outputs that apps can understand. It provides compatibility modes for SDL, Apple GameController, Generic HID, and experimental Xbox HID targets, with common diagnostics and checks in one repo-controlled workflow.
See docs/user/compatibility.md for current backend, output-mode, and device-support status.
Compatibility mode does not require DriverKit. The generated SwifterKit system extension is a vendor-defined integrity relay for self-test and diagnostics. It deliberately does not publish a second consumer gamepad. Self-test reads the signed host entitlement. Relay delivery is required for an entitled host and reported as optional and inconclusive when the entitlement is absent.
- Drag
OpenJoystickDriver.appto/Applications. - Open
OpenJoystickDriver.app. - The app intentionally has no visible UI. Start and inspect it with the installed bundle command below.
- Grant Input Monitoring and Accessibility to OpenJoystickDriver when macOS asks.
- Connect a supported controller.
- Run
controller stateorcontroller watchfrom the CLI to confirm buttons and sticks.
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 |
|---|---|---|
| Most games, Steam, emulators, SDL apps | Compatibility + SDL 2/3 |
Stable app-facing identity and mapping. |
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 Microsoft HID | Compatibility + Xbox 360 HID or Xbox One HID |
Experimental spoof identities for targeted testing. |
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. |
| DriverKit relay installation fails | Compatibility output still works. --headless test tests Compatibility and reports relay diagnostics as optional when the signed host lacks relay access. |
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:
brew install libusb
./scripts/ojd catalog regenerate --check
./scripts/ojd check profiles
./scripts/ojd test parsers-macos14
./scripts/ojd check driverkit
swift buildFor application, generated DriverKit relay, 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