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:

text
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:

lua
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:

json
{
  "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.version matches lua54 'yes' in your fxmanifest.lua.
  • nonstandardSymbol tells 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.globals lists names the script defines somewhere the server cannot trace. Add your own: ESX, QBCore, a Config table from config.lua. If a typings extension already declares lib and exports, 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:

lua
local players = ESX.GetPlayers()
for i = 1, #player do   -- 'player' is not defined: should be 'players'
end

Turn 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:

lua
---@diagnostic disable-next-line: undefined-global
local x = SomeOtherResourceGlobal

Annotate your own code

LuaLS reads ---@ comments. A few lines make your own functions self-documenting and give callers autocomplete:

lua
---@param plate string
---@param coords vector3
---@return boolean
local function isPlateNear(plate, coords)
    -- ...
end

If 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:

toml
column_width = 120
indent_type = "Spaces"
indent_width = 4
quote_style = "AutoPreferSingle"

Then in the VS Code settings:

json
{
  "[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 β†’

Keep reading