Ship code from your couch. Control your AI coding assistant with a gamepad.
VibePad is a macOS menu bar app that turns your gamepad into a full coding controller โ optimized for AI-assisted development with Claude Code and Codex CLI.
Accept AI suggestions, scroll through code, switch apps, dictate with voice โ all without touching your keyboard.
- Connect your PS5, Xbox, or MFi controller
- VibePad maps buttons to keyboard shortcuts optimized for Claude Code and Codex CLI
- Accept AI suggestions, navigate code, switch tabs โ all from your controller
- Two-layer mapping โ default layer + L1 modifier layer doubles your button count
- Smart Paste โ clipboard-aware: Ctrl+V for images, Cmd+V for text
- Left stick = arrow keys โ hysteresis thresholds and hold-to-repeat
- Right stick = scroll โ continuous smooth scrolling
- L1+stick = app switch & mouse โ switch apps or move the cursor without leaving the couch
- Mouse clicks โ L3/R3 for left/right click
- Hold-to-repeat โ configurable per-button repeat delay and interval
- Trigger modes โ fire on press, release, or both (e.g. hold-to-talk for voice input)
- HUD overlay โ shows action labels on every button press
- JSON config โ full customization at
~/.vibepad/config.json - Menu bar app โ lives in your status bar, launch at login
- Download the latest release from GitHub Releases
- Move VibePad.app to Applications
- Launch and grant Accessibility permission when prompted
Accessibility permission is required for keyboard injection โ this is how VibePad sends keystrokes to your apps.
VibePad writes its default config to ~/.vibepad/config.json on first launch. Edit this file to customize your layout, then restart the app.
{
"version": 1,
"profile": "claude-code",
"mappings": {
"buttonA": { "type": "keystroke", "key": "return", "modifiers": [] },
"buttonX": { "type": "keystroke", "key": "c", "modifiers": ["control"] },
"buttonMenu": { "type": "typeText", "text": "/" }
},
"l1Mappings": {
"buttonB": { "type": "keystroke", "key": "delete", "modifiers": [] }
},
"stickConfig": {
"leftStickDeadzone": 0.3,
"rightStickDeadzone": 0.2,
"arrowPressThreshold": 0.5,
"arrowReleaseThreshold": 0.3,
"scrollSensitivity": 15.0
}
}keystrokeโ press a key with optional modifiers.keyis any key name from the key list,modifiersis an array of"command","control","shift","option".typeTextโ type a string character by character. Use\nfor Enter.smartPasteโ clipboard-aware paste: sends Ctrl+V when the clipboard contains an image, Cmd+V otherwise. Nokeyormodifiersneeded.leftMouseClick/rightMouseClickโ simulate a mouse click at the current cursor position.
buttonA, buttonB, buttonX, buttonY, dpadUp, dpadDown, dpadLeft, dpadRight, leftShoulder, rightShoulder, leftTrigger, rightTrigger, leftThumbstickButton, rightThumbstickButton, buttonMenu, buttonOptions
Note: leftShoulder (L1) is reserved as the modifier layer key and cannot be remapped.
Letters (a-z), numbers (0-9), return, escape, space, tab, delete, forwardDelete, arrows (upArrow, downArrow, leftArrow, rightArrow), punctuation (grave, minus, equal, leftBracket, rightBracket, backslash, semicolon, quote, comma, period, slash), function keys (f1-f12).
- macOS 14 (Sonoma) or later
- PS5 DualSense, Xbox, or MFi controller
- Accessibility permission (for keyboard injection)
Built with Swift, AppKit, GameController framework, and CGEvent.
Inspired by enjoy2 โ a macOS joystick-to-keyboard mapper.
Add the badge to your project README:
[](https://vibepad.now)PolyForm Noncommercial 1.0.0 โ source available, non-commercial use permitted. See LICENSE for details.


