FiveM keybind with RegisterKeyMapping
Learn how to create a configurable key in FiveM with RegisterKeyMapping and RegisterCommand: the player rebinds it in Settings. Includes held keys (+/-) and when to use IsControlJustPressed.
The problem
You want an action in your script to fire when a key is pressed (for example, opening a menu or using an item), but you don't know how to bind it properly or how to let the player change it to their liking.
The cause
There are two different approaches in FiveM and they're often confused. RegisterKeyMapping creates a REAL binding that shows up in FiveM Settings (Settings > Key Bindings) and that the player can rebind. In contrast, IsControlJustPressed/IsControlPressed read game controls by their ID and are not user-rebindable for your action. Using the wrong approach gives you keys that clash with other resources or that the player can't change.
The solution
Register a command with RegisterCommand and bind it to a default key with RegisterKeyMapping. The player will be able to rebind it from FiveM Settings. For keys held down, use the + (press) and - (release) prefix:
-- client.lua
-- 1) Simple action (single press): key E opens something
RegisterCommand('myaction', function()
-- Your logic when the key is pressed
print('Key pressed! Opening action...')
-- e.g.: TriggerEvent('myresource:openMenu')
end, false) -- false = the player CAN use the command (not ACE-restricted)
-- 2) Bind 'myaction' to key E by default.
-- The player sees it under Settings > Key Bindings and can change it.
RegisterKeyMapping(
'myaction', -- command name (must match)
'Description shown in Settings', -- text shown in the FiveM menu
'keyboard', -- device: 'keyboard', 'mouse', 'pad_*'
'E' -- default key
)
-- 3) HELD key: use commands with the + and - prefix
-- FiveM calls '+sprint' on press and '-sprint' on release.
local sprinting = false
RegisterCommand('+sprint', function()
sprinting = true
end, false)
RegisterCommand('-sprint', function()
sprinting = false
end, false)
-- You only register the binding for the '+' command
RegisterKeyMapping('+sprint', 'Sprint (hold)', 'keyboard', 'LSHIFT')
-- Best practice: only run an active loop WHILE the key is held,
-- instead of checking the state every frame forever.
CreateThread(function()
while true do
if sprinting then
-- per-frame logic only when needed
Wait(0)
else
Wait(250) -- idle, almost no cost
end
end
end)Step by step
- 1.Create the command with RegisterCommand('myaction', fn, false). The third parameter set to false lets any player use it; set it to true only if you want to restrict it with ACE permissions.
- 2.Bind that command to a default key with RegisterKeyMapping('myaction', 'Text in Settings', 'keyboard', 'E'). The name must match the command name EXACTLY.
- 3.Put these calls on the client side (client.lua) at the top level of the script, not inside an event, so the binding registers when the resource loads.
- 4.The player rebinds the key in FiveM Settings > Key Bindings (look for your description). No code changes are needed to change it.
- 5.For held keys, register two commands: '+myaction' (on press) and '-myaction' (on release), and call RegisterKeyMapping only on the '+' one.
- 6.Use RegisterKeyMapping/RegisterCommand for rebindable user actions. Reserve IsControlJustPressed(0, control) and IsControlPressed to read game controls by ID when you need direct per-frame detection.
- 7.Avoid spamming: don't run heavy logic in a while loop with a permanent Wait(0). Activate the frame loop only while the key is held and increase the Wait when idle.
Related guides
Last updated: 2026-06-29. Crxative-M is not affiliated with Cfx.re or Rockstar Games.
