Need a flexible and persistent keybind system for your Roblox game? EZ Bind makes handling custom keybinds effortless with a clean API and built-in support for multiple devices.
EZ Bind – Drop-in Keybinding System for Luau
TL;DR: Plug in the module, register actions, call
Load()once, and you’ve got fully-customizable, cross-device keybinds that persist between sessions.
Features
- Fully customizable keybinds at runtime
- Overwrite protection (auto-unbinds old key if reused)
- Key combinations (bind multiple keys to one action)
- Device-aware (Keyboard/Mouse and Gamepad supported)
- Persistent save system with throttled DataStore + cache
File Structure
Getting Started
1. Server Setup
require(game.ReplicatedStorage.Modules.Keybinds.Data).Init()
2. Client Setup
require(game.ReplicatedStorage.Modules.Keybinds.ActionRegistry)
require(ReplicatedStorage.Modules.Keybinds.Client).Init()
3. Action Setup
local Keybinds = require(ReplicatedStorage.Modules.Keybinds)
local Sprint = require(script.Actions.Sprint)
Sprint.Init()
Keybinds.Register(
"Sprint", -- Name
Sprint.DefaultKey, -- Keyboard
Sprint.DefaultGamepad, -- Gamepad
Sprint.Action, -- Callback
{ doubleTap = true,
tapWindow = 1 } -- Optional
)
API
| Method | Description |
|---|---|
Register(name, kb, gp?, callback, opts?) |
Registers a new action with optional gamepad input and settings. |
SetInput(name, inputList?) |
Assigns one or more inputs to the action. Pass nil to unbind. |
SetKey(name, Enum.KeyCode?) |
Shortcut for SetInput with a single KeyCode. |
GetInput(name): {Input}? |
Returns the current inputs for the given action (based on active input scheme). |
GetKey(name): Enum.KeyCode? |
Returns the first key assigned to the action in the active scheme, or nil if unbound. |
Load(dataTable) |
Loads keybinds from a saved data table (typically from the server). |
Events
Keybinds.Overwritten:Connect(function(old, new) end)Keybinds.SchemeChanged:Connect(function(scheme) end)
Example Action Module
type Input = Enum.KeyCode | Enum.UserInputType
local PrintAction = {} :: {
DefaultKey: Input,
DefaultGamepad: Input,
Action: (string, Enum.UserInputState, InputObject) -> (),
}
PrintAction.DefaultKey = Enum.KeyCode.P
PrintAction.DefaultGamepad = Enum.KeyCode.ButtonY
PrintAction.DefaultKeyCombo = {Enum.KeyCode.Q, Enum.KeyCode.E}
PrintAction.DefaultGamepadCombo = {Enum.KeyCode.ButtonX, Enum.KeyCode.ButtonY}
local function onPress()
print("Key was pressed!")
end
function PrintAction.Action(_name, state, _io)
if state == Enum.UserInputState.Begin then
onPress()
end
end
return PrintAction
Save System Notes
- Uses
DataStoreService+ server cache - Save is debounced (0.4s) and throttled (6s)
- On shutdown, remaining cache is flushed
- Empty or bad data is ignored gracefully
License
MIT – use it in any personal or commercial project.
Feedback
Found a bug or want to suggest something? Reply below.

