Engineering
Typing your FiveM Lua with annotations
Use Lua Language Server annotations in FiveM scripts: ---@param, ---@return, ---@class and ---@field for player and config tables, ---@alias for string unions, ---@type, typing exports and events, and how annotations catch bugs before the server starts.
Overview
Lua is dynamically typed, which is great for quick scripts and painful in a 5,000-line resource. Lua Language Server annotations — special ---@ comments — give you types without changing how the code runs: autocompletion for your own tables, warnings for wrong arguments and documentation on hover.
Functions
---@alias MoneyAccount 'cash' | 'bank'
---Pays a player and logs the reason.
---@param src number Server ID of the player
---@param account MoneyAccount
---@param amount integer Must be positive
---@param reason? string Optional log reason
---@return boolean ok
local function pay(src, account, amount, reason)
if amount <= 0 then return false end
return Bridge.addMoney(src, account, amount, reason)
end
pay(1, 'cahs', 100) -- warning: 'cahs' is not a MoneyAccountTable shapes with @class
---@class GarageConfig
---@field label string
---@field coords vector3
---@field spawn vector4
---@field jobs? string[] Only these jobs may use it
---@type table<string, GarageConfig>
Config.Garages = {
legion = {
label = 'Legion Square',
coords = vec3(215.8, -810.1, 30.7),
spawn = vec4(229.7, -800.1, 30.5, 157.8),
},
}Now Config.Garages.legion. autocompletes its fields, and a missing spawn or a typo like cords shows a warning. Config design is covered in config.lua best practices.
The annotations you will use most
| Annotation | Use |
|---|---|
---@param name type | Function parameter (name? for optional) |
---@return type name | Return value |
---@class Name | Declare a table type |
---@field name type | A field of the class above |
---@type T | Type of the next variable |
---@alias Name 'a' | 'b' | Named union type |
---@deprecated | Warn when something old is used |
---@meta | A definitions-only file (for exports other resources call) |
Typing exports for other resources
Put ---@meta definition files in your resource (for example types/exports.lua) describing its exports; other developers can add the resource to their workspace.library and get completion for exports.yourres:.... ox_lib does exactly this, which is why its functions autocomplete — see VS Code setup.
Frequently asked questions
Do Lua annotations slow down FiveM?
No. They are comments and are ignored when the script runs.
What tool reads the annotations?
The Lua Language Server (the “Lua” extension in VS Code).
How do I mark an optional parameter?
Add a question mark: ---@param reason? string.
Can I type a table of configs?
Yes: declare a ---@class with ---@fields and use ---@type table<string, YourClass>.
Need this built, not just explained?
Ten years of FiveM work, from Lua to NUI
Custom resources, React NUI, ESX / QBCore / Qbox integration, OneSync performance audits and security reviews — plus the websites and SEO around your server brand.
Related guides
- Getting startedSetting up VS Code for FiveM scriptingInstall the Lua extension (Lua Language Server by sumneko/LuaLS). Clone Overextended’s fivem-lls-addon — the replacement for the discontinued CfxLua IntelliSense extension — into a folder for Lua addons, point workspace.userThirdParty at that folder in a .luarc.json, and add ox_lib to workspace.library. For JavaScript/TypeScript, install @citizenfx/client and @citizenfx/server typings.
- Getting startedLua tables for FiveM developersA table can be an array ({ 'a', 'b' }, indexed from 1) or a dictionary ({ price = 5 }), or both. Loop arrays with ipairs and dictionaries with pairs. #t counts only the array part up to the first gap. Tables are passed by reference, so copying requires a copy function. json.encode and json.decode convert tables for NUI, HTTP and databases.