PiTyUs.Hire me

Engineering

Designing a config.lua people can actually use

Design FiveM script configs well: what belongs in config vs code, shared vs server-only config (secrets), grouping and naming, sensible defaults, validation at startup, vectors and job tables, framework/inventory switches, comments in English, and keeping configs editable under escrow.

Updated 9 min readBy PiTyUs · FiveM developer

Overview

The config is the part of your script every server owner touches. A good one makes installation boring — in the best way. A bad one produces support tickets, leaked webhooks and servers where a typo in a coordinate crashes the resource on start.

Shared vs server-only config

fxmanifest.lualua
shared_script 'config.lua'          -- sent to clients
server_script 'config_server.lua'   -- never leaves the server

escrow_ignore { 'config.lua', 'config_server.lua', 'locales/*.json' }

Everything in a shared or client file is downloaded by every player and readable. Discord webhooks, API keys and payout amounts belong in the server-only file — see anticheat basics.

A clear shape

config.lualua
Config = {}

Config.Debug = false
Config.Framework = 'auto'      -- 'auto' | 'esx' | 'qb' | 'qbx'
Config.Inventory = 'ox'        -- 'ox' | 'qb'

Config.Garages = {
    legion = {
        label = 'Legion Square',
        coords = vec3(215.8, -810.1, 30.7),
        spawn = vec4(229.7, -800.1, 30.5, 157.8),
        jobs = nil,                -- nil = everyone
    },
}

Config.Impound = {
    fee = 250,
    jobs = { police = 2 },     -- job = minimum grade
}
  • Group by feature, not by type.
  • Use vec3/vec4 for positions — readable and fast.
  • Keep English comments short and on the settings people change.
  • Avoid functions in configs unless they are explicit hooks (e.g. Config.CanUse = function(src) ... end).

Validate at startup

server.lualua
for id, g in pairs(Config.Garages) do
    assert(type(g.label) == 'string', ('Config.Garages.%s.label must be a string'):format(id))
    assert(type(g.spawn) == 'vector4', ('Config.Garages.%s.spawn must be vec4(x, y, z, heading)'):format(id))
end

A clear message at start beats a nil error an hour later in the middle of a scene. Annotate config shapes for editor help — see Lua annotations.

Defaults that work

Ship with coordinates, prices and toggles that work on a fresh server, Config.Debug = false, and translations in a locale file rather than in the config — see localization. Document every option in your README — see script documentation.

Frequently asked questions

What should go in a FiveM config.lua?

Values server owners change: locations, prices, jobs, toggles. Logic stays in code.

Where should I put webhooks and API keys?

In a server-only config file loaded with server_script, never in shared or client files.

How do I keep configs editable in escrowed resources?

List them in escrow_ignore in the fxmanifest.

Should configs contain translations?

Better in locale files, so translators do not need to touch the config.

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