Write software entirely using an Xbox controller and your voice. Maps every control you need for a voice-first, multi-terminal, agentic workflow to your gamepad.
Sit, stand, or walk around while developing software faster than ever.
-
Face buttons — Common keys (Return, Escape, Backspace, Tab) with modifier layers
-
D-pad — Arrow keys, with modifier layers for tab and window switching
-
Two modifier layers — Hold LT or LB to access extended bindings on every button
-
Left stick — Moves mouse cursor (fallback for when buttons won't do)
-
Right stick — Smooth scrolling
-
Universal mouse buttons — Any button combo without a keyboard binding automatically emits a virtual mouse button (10–23), distinguished across modifier layers by held modifier keys (Option for +LT, Control for +LB). Mappable in utilities like SuperWhisper or BetterTouchTool
-
JSON config — All bindings stored in
~/.config/codecontroller.json, editable without recompiling
- macOS 10.15+
- Xbox One wireless controller (known supported — other controllers may work via Apple's Game Controller framework)
- Voice transcription — CodeController replaces your keyboard, so you need a voice-to-text app to type. SuperWhisper is recommended, but Whisper Transcription, Talon, or macOS Dictation also work
Check the Releases page for pre-built binaries.
Requires Swift toolchain (Xcode or Command Line Tools).
- Build:
./build.sh - Copy to Applications:
cp -R CodeController.app /Applications/ - Launch:
open /Applications/CodeController.app - Grant Accessibility permission when prompted (or manually in System Settings > Privacy & Security > Accessibility)
SuperWhisper is a macOS voice-to-text app. Bind controller buttons to SuperWhisper for hands-free dictation:
- Install SuperWhisper
- Open SuperWhisper Settings
- Set Mouse Shortcut to Mouse Button 14 (RT)
BetterTouchTool can map any of the virtual mouse buttons (10–23) to system actions that CodeController can't do natively — switching Spaces, launching apps, window snapping, etc. Modifier layers emit the same button numbers but with held modifier keys (Option for +LT, Control for +LB), so BTT can distinguish them by matching on modifier state.
- Open BetterTouchTool Settings
- Enable Advanced > High Level Mouse Event Recognition
- Import the included preset: Preset > Import Preset, then select
codecontroller_triggers.bttpresetfrom the app bundle (right-click CodeController.app > Show Package Contents > Contents/Resources) or the Releases page - The preset maps LT+D-Left / LT+D-Right to switch Spaces (left/right)
Add your own triggers by assigning a mouse button to any action in BetterTouchTool's preferences.
The default bindings map Y to Tab. Claude Code changed Tab from extended thinking toggle to autocomplete. To restore Tab as the thinking toggle, add this to ~/.claude/keybindings.json:
{
"bindings": [
{
"context": "Chat",
"bindings": {
"tab": "chat:thinkingToggle"
}
}
]
}Mouse buttons: Every button has a default mouse button number shown in the Mouse # column. All three layers (Base, +LT, +LB) use the same button numbers (10–23) — layers are distinguished by modifier keys held during the event: none for Base, Option for +LT, Control for +LB. The config file contains keyboard overrides — remove an override to expose the underlying mouse button. These virtual mouse buttons can be mapped in apps like SuperWhisper or BetterTouchTool.
| Input | Action | Mouse # |
|---|---|---|
| Left Stick | Mouse cursor | |
| Left Stick Click | Left click | 16 |
| Right Stick | Scroll | |
| Right Stick Click | Right click | 17 |
| Button | Role |
|---|---|
| LT (Left Trigger) | Hold to activate +LT layer |
| LB (Left Bumper) | Hold to activate +LB layer |
| Button | Key | Action | Mouse # |
|---|---|---|---|
| A | Return |
Submit | 10 |
| B | Escape |
Cancel | 11 |
| X | Backspace |
Delete | 12 |
| Y | Tab |
Autocomplete / thinking | 13 |
| RT | 14 | ||
| RB | 15 | ||
| D-Up | Up |
Navigate | 18 |
| D-Down | Down |
Navigate | 19 |
| D-Left | Left |
Navigate | 20 |
| D-Right | Right |
Navigate | 21 |
| Back | Ctrl+O |
Toggle transcript | 22 |
| Menu | / |
Slash commands | 23 |
| Button | Key | Action | Mouse # |
|---|---|---|---|
| LT+A | Space |
Scroll page | 10+Opt |
| LT+B | 11+Opt | ||
| LT+X | 12+Opt | ||
| LT+Y | Shift+Tab |
Cycle permission mode | 13+Opt |
| LT+RT | 14+Opt | ||
| LT+RB | 15+Opt | ||
| LT+LS | 16+Opt | ||
| LT+RS | 17+Opt | ||
| LT+D-Up | <Accessibility> |
Cycle windows | 18+Opt |
| LT+D-Down | <Accessibility> |
Cycle windows | 19+Opt |
| LT+D-Left | Cmd+Shift+[ |
Prev tab | 20+Opt |
| LT+D-Right | Cmd+Shift+] |
Next tab | 21+Opt |
| LT+Back | Ctrl+E |
Toggle show all | 22+Opt |
| LT+Menu | 23+Opt |
| Button | Key | Action | Mouse # |
|---|---|---|---|
| LB+A | 10+Ctrl | ||
| LB+B | Cmd+W |
Close tab | 11+Ctrl |
| LB+X | 12+Ctrl | ||
| LB+Y | Cmd+T |
New tab | 13+Ctrl |
| LB+RT | 14+Ctrl | ||
| LB+RB | 15+Ctrl | ||
| LB+LS | 16+Ctrl | ||
| LB+RS | 17+Ctrl | ||
| LB+D-Up | 18+Ctrl | ||
| LB+D-Down | 19+Ctrl | ||
| LB+D-Left | 20+Ctrl | ||
| LB+D-Right | 21+Ctrl | ||
| LB+Back | Ctrl+B |
Background task | 22+Ctrl |
| LB+Menu | 23+Ctrl |
Bindings are stored in ~/.config/codecontroller.json. A default config is written on first launch. Edit the file and use Reload Config from the menu bar to apply changes.
The config only needs entries for keyboard overrides. Any button combo not in the config automatically emits its mouse button.
| Type | Description | Fields |
|---|---|---|
key |
Hold key (press on button down, release on up) | key, modifiers |
tap |
Fire once on press with explicit modifier key events — use for system shortcuts (e.g. Cmd+Shift+[) that don't register with key |
key, modifiers |
leftClick |
Left mouse click | — |
rightClick |
Right mouse click | — |
cycleWindows |
Raise next window of frontmost app | — |
{ "key": "return", "type": "key" }
{ "key": "w", "type": "key", "modifiers": ["command"] }
{ "key": "[", "type": "tap", "modifiers": ["command", "shift"] }
{ "type": "leftClick" }
{ "type": "cycleWindows" }- Letters:
athroughz - Numbers:
0through9 - Editing:
return,tab,space,backspace,escape,delete - Arrows:
up,down,left,right - Function:
f1throughf12 - Punctuation:
/,[,],-,=,;,',,,.,` - Navigation:
home,end,pageup,pagedown
commandorcmdshiftoptionoraltcontrolorctrl
Base buttons:
a, b, x, y, rt, rb, ls, rs, back, menu, dpad_up, dpad_down, dpad_left, dpad_right
Prefix with lt+ or lb+ for modifier layers (e.g., lt+a, lb+dpad_left).
Output is logged to ~/Library/Logs/CodeController.log.