This guide covers the show/hide workflow specifically. For the full keybinds API reference, see Setup
Keybinds.
How Keybinds Work
Before writing any code, it helps to know three things about how Overlayed handles keybinds:- Keybinds are defined at setup time. You declare every keybind (with a default key combination) in your
overlayed()config. You can change a keybind’skeysandmodeat runtime, but you cannot add brand new keybind names after setup. - Key presses are captured by Overlayed’s native keyboard hook. Keybinds fire while the game is focused and
fullscreen - you don’t need Electron’s
globalShortcut, and there’s nothing to register with the OS. - User changes persist automatically. The config you pass in is only the default. When your code calls
updateKeybind(typically from your keybind settings UI), the new binding is saved to disk and used from then on.
Wiring a Keybind to a Window
Define the keybind
Add a keybind to your
overlayed() setup. The name (toggleHud here) is yours to choose - you’ll use it to
listen for the keybind later.main.ts
keysis an array of KeyboardEvent#code values -"KeyO", not"o". Every entry must be held at once, so["AltLeft", "KeyO"]means Alt + O. Use keycode.info to look up codes.modeis"toggle"(press once to fire) or"hold"(fires on press and release).
Create the window
Create the window you want to control. For a window rendered inside the game, use See Creating Windows for the difference between in-game and out-of-game windows.
createInGameWindow:Toggle vs. Hold
Which mode you pick changes which events you should listen to. A toggled HUD listens totoggle; a hold-to-peek
scoreboard listens to down and up.
- Toggle mode
- Hold mode
The
toggle event fires once per full key press. The user must release the keys before the keybind can fire
again - holding the combination down does not re-trigger it.Conditionally Blocking the Keybind
Sometimes showing the window doesn’t make sense - for example, a scoreboard when the user isn’t in a match. Return a string (the rejection reason) from atoggle or down listener to block it:
hold keybinds the matching up
event won’t fire.
Letting Users Rebind Keys
The keys you configure are just defaults. To support user customization, build a settings UI on top of these methods:FAQ
Do keybinds work while the game is fullscreen and focused?
Do keybinds work while the game is fullscreen and focused?
Yes. Keybinds are captured through Overlayed’s native keyboard hook in the game, so they fire while the game has
focus - including exclusive fullscreen. The overlay window itself doesn’t need focus, and it doesn’t matter
whether the window is currently hidden.
What if my keybind conflicts with a game keybind?
What if my keybind conflicts with a game keybind?
Overlayed observes key presses; it doesn’t stop the game from also acting on them. Pick defaults that rarely
clash with common game binds (e.g. Alt-modified combinations rather than bare letters), and give
users a way to rebind. When users update keybinds, validate that two of your own keybinds don’t end up with the
same combination.
What happens when extra keys are held down?
What happens when extra keys are held down?
Matching runs on every key press against the full set of currently held keys. A keybind whose keys exactly
match that set wins; if nothing matches exactly, any keybind whose keys are all held fires - so
["AltLeft", "KeyX"] triggers even if an unrelated key is also down. Be careful defining one keybind as a
subset of another (like ["AltLeft", "KeyX"] and ["AltLeft", "ShiftLeft", "KeyX"]): because keys arrive one
at a time, pressing Alt, then X, then Shift exactly matches the two-key bind
mid-sequence and fires it before the three-key bind.Can one keybind control multiple windows?
Can one keybind control multiple windows?
Yes.
on supports multiple listeners per keybind, so several windows can react to the same press. The reverse
also works: nothing stops two keybind names from pointing at the same window.Where are user keybind changes stored?
Where are user keybind changes stored?
In a
keybinds.json file in your app’s data directory. Overlayed manages it entirely - updateKeybind and
updateKeybinds write to it, and getConfig() reads from it. You never need to touch the file yourself.Do I need to unregister keybinds on quit?
Do I need to unregister keybinds on quit?
No. Keybind listening is torn down automatically when the app quits. Since keybinds aren’t OS-level global
shortcuts, there’s nothing left registered with the system after a crash either.
Can I add new keybinds at runtime?
Can I add new keybinds at runtime?
No - keybind names are fixed at setup. You can update an existing keybind’s
keys and mode at runtime, but
new keybinds require declaring them in the overlayed() config. Also note there is currently no migration path
for renaming a keybind, so choose names you can live with.My keybind isn't firing - how do I debug it?
My keybind isn't firing - how do I debug it?
Check these in order:
- Key codes: make sure you’re using
KeyboardEvent#codevalues ("KeyX","Digit1","Backquote"), not characters. Unknown keys are logged as errors. - Left/right modifiers:
"AltLeft"and"AltRight"are different keys. - Logs: every trigger is logged as accepted or rejected (with your rejection reason), which tells you whether the keybind fired but the listener blocked it. See Logging.
- Paused listening: verify you didn’t call
pauseKeybindListening()without a matching resume.
Next Steps
Keybinds Reference
The full keybinds API: events, updating, pausing, and rejection.
Creating Windows
In-game vs. out-of-game windows and how to create them.
Render Windows
Layers, input, and the extra methods on in-game windows.
Blocking Game Input
Prevent input from reaching the game while your window is open.

