FiveM VS Code setup: Lua language server, natives, no false warnings
VS Code full of 'Undefined global' warnings on FiveM Lua? Set up a Lua language server, natives typings, workspace settings, a formatter and fast natives search.
You open a perfectly fine script in VS Code and it looks like this:
Undefined global `PlayerPedId`.Every native, exports, ESX and QBCore gets a yellow underline, and real mistakes drown in the noise. This guide sets up VS Code so it understands FiveM Lua, and only warns you about things that are actually wrong.
Install a Lua language server
In the Extensions panel, install a Lua language server extension. The widely used one is the "Lua" extension by sumneko, which is built on Lua Language Server (LuaLS). It gives you completion, go to definition, rename and diagnostics.
Open your resources folder as the workspace (not a single file), so the server can see every script and the settings you are about to add.
Add FiveM natives definitions
Plain LuaLS has no idea what GetEntityCoords takes. The community maintains typings for FiveM / CfxLua: a set of annotation files that describe the natives, the Cfx.re globals and the extra Lua syntax FiveM allows. Search the Extensions panel for "CfxLua" or "FiveM natives", or look for a "FiveM" addon in the LuaLS addon manager, and pick the one that is actively maintained.
With them installed you get signatures when you type:
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)Hover over a native and the parameters and return types show up. Most typings also include exports, lib annotations if you add the ox_lib definitions, and the cache table.
Tip: Extension names and settings change over time. If a setting below does not exist in your version, check the extension's own README, which is always more current than a tutorial.
Workspace settings
Create .vscode/settings.json at the root of your resources folder. This keeps the settings with the project, so everyone who opens it gets the same behaviour:
{
"Lua.runtime.version": "Lua 5.4",
"Lua.runtime.nonstandardSymbol": [
"/**/", "`", "+=", "-=", "*=", "/=", "<<=", ">>=", "&=", "|=", "^="
],
"Lua.diagnostics.globals": [
"ESX", "QBCore", "Config", "Locales", "PlayerData",
"lib", "cache", "exports"
],
"Lua.workspace.checkThirdParty": false,
"Lua.workspace.ignoreDir": [".vscode", "node_modules", "dist"]
}What each part does:
Lua.runtime.versionmatcheslua54 'yes'in yourfxmanifest.lua.nonstandardSymboltells the parser that FiveM's compound assignment (x += 1) and backtick hashes are valid. Without it, perfectly good code is flagged as a syntax error.Lua.diagnostics.globalslists names the script defines somewhere the server cannot trace. Add your own:ESX,QBCore, aConfigtable fromconfig.lua. If a typings extension already declareslibandexports, you can drop them from the list.
Only add real globals. If you silence everything, you lose the warning that catches a misspelled variable, which is one of the best things the editor does for you.
Fix the warnings that are real
Some warnings are the editor doing its job:
local players = ESX.GetPlayers()
for i = 1, #player do -- 'player' is not defined: should be 'players'
endTurn Lua.diagnostics.globals into a short, deliberate list and every remaining Undefined global is a typo or a missing local. That is also the quickest way to find accidental globals, which the resmon guide lists as a performance and bug source.
For one-off cases, an inline comment is better than a global setting:
---@diagnostic disable-next-line: undefined-global
local x = SomeOtherResourceGlobalAnnotate your own code
LuaLS reads ---@ comments. A few lines make your own functions self-documenting and give callers autocomplete:
---@param plate string
---@param coords vector3
---@return boolean
local function isPlateNear(plate, coords)
-- ...
endIf you build a library other scripts call through exports, putting these annotations on the exported functions pays off the most.
Format on save
Install StyLua (the extension for the StyLua formatter) or use the language server's own formatter. For StyLua, add a stylua.toml next to your resources:
column_width = 120
indent_type = "Spaces"
indent_width = 4
quote_style = "AutoPreferSingle"Then in the VS Code settings:
{
"[lua]": {
"editor.defaultFormatter": "JohnnyMorganz.stylua",
"editor.formatOnSave": true
}
}Check the formatter's ID in the Extensions panel if it does not trigger. StyLua may not like FiveM-only syntax such as backtick hashes, so run it on a copy first if your scripts use them heavily.
Search the natives
The editor tells you the signature; the official natives reference tells you what the native really does, with notes from other developers. The natives pages are at docs.fivem.net/natives, and the search box finds a native by name or description. Two habits help:
- Search by what you want, not the exact name: "get closest vehicle", "ped bone".
- Read the Cfx.re native first, then the GTA V reference text, since some natives behave differently on the FiveM build.
For client/server details, see client and server events and Wait and threads.
Checklist
| Symptom | Fix |
|---|---|
Undefined global on every native |
Install natives typings (CfxLua / FiveM addon) for the Lua language server |
ESX or QBCore underlined |
Add them to Lua.diagnostics.globals in .vscode/settings.json |
x += 1 shown as a syntax error |
Add the compound operators to Lua.runtime.nonstandardSymbol |
| Backtick hash flagged | Add the backtick to nonstandardSymbol |
| Warnings everywhere after silencing | Keep the globals list short so typos still show up |
| Formatter does nothing | Set editor.defaultFormatter for [lua] and enable format on save |
Quick answers
Why does VS Code say 'Undefined global' for natives like PlayerPedId?
The Lua language server only knows standard Lua. FiveM natives, exports, ESX or QBCore are globals it has never heard of. Add typings for natives and list your framework globals in Lua.diagnostics.globals.
Do I need to change the Lua version in the settings?
Set Lua.runtime.version to Lua 5.4, since that is what FiveM scripts run on with lua54 'yes' in the manifest. It also stops the editor flagging syntax that FiveM accepts.
Which formatter should I use for FiveM Lua?
StyLua works well and is configured by a small stylua.toml in the repository. The formatter built into the Lua language server also works if you want one extension less.
Scripts that skip this problem
Item Creator V2Create usable items with animations, props, effects and more β without writing code.View script β
Quest CreatorA visual editor for quests and NPC dialogues, built node by node in game.View script β
Shop CreatorBuild a shop in under a minute β owners, employees, vaults and robberies included.View script β