FiveM Docs
Core Resources

esx_lib

esx_lib reference for ESX Legacy. Load xLib, use callbacks, cache, points, NUI, rate limiting, tokens, pub/sub and every module with signatures.

esx_lib is the official ESX utility library. It exposes a global xLib table that lazily loads modules (callbacks, player cache, points, NUI helpers, streaming, validation, rate limiting and more) into any resource that includes @esx_lib/imports.lua. es_extended itself is built on top of it, so every ESX Legacy server needs esx_lib started first.

Overview

FactValue
Resource nameesx_lib (the loader hardcodes this name, do not rename the folder)
Version1.0.0 (legacyversion '1.16.3' in fxmanifest)
SideShared (client and server modules)
DependenciesNone. oxmysql is only needed by the server-side schema and catalog modules, which run inside es_extended.
Used byes_extended, esx_identity, esx_inventory, esx_menu_default, esx_menu_dialog, esx_multicharacter, esx_progressbar, esx_skin, esx_whitelist
GlobalxLib (with fields name, side, debug)

Parts of esx_lib are adapted from ox_lib by Linden (LGPL-3.0). Those files carry the original notice in the source.

Installation and load order

esx_lib ships in the [core] folder of esx_core. Start it before es_extended:

server.cfg
ensure oxmysql
ensure esx_lib
ensure es_extended

To use xLib in your own resource, add the import as a shared script and declare the dependency:

fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'

shared_scripts {
    '@esx_lib/imports.lua',
    '@es_extended/imports.lua',
}

client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }

dependencies {
    'es_extended',
    'esx_lib',
}

How lazy loading works

imports.lua creates the xLib table with an __index metamethod. The first time you read xLib.<name>, it loads imports/<name>/shared.lua plus imports/<name>/client.lua or imports/<name>/server.lua from esx_lib and runs them inside your resource. Modules you never touch are never loaded.

If no module folder exists for a name, xLib returns a proxy that calls exports.esx_lib:<name>(...). This is how functions that must live in one central place (callback validation, pub/sub registry, triggerClientEvent) are shared by every resource.

Global require is replaced

imports.lua sets require = xLib.require in your resource. Plain require('module') therefore loads files from your resource through LoadResourceFile, not from the standard Lua package path. See require.

Module summary

ModuleSidePurpose
addKeybindClientRegister key mappings with press and release handlers
blipsClientCreate and remove map blips from an options table
cacheClientCached ped, vehicle, seat, weapon, playerId, serverId, coords
callbackClient, ServerClient/server callbacks with validation, timeouts and rate limits
classSharedMinimal class system with constructor and new
colorsSharedESX brand colors and UI theme from convars
duiClientDUI (browser texture) class
entityClientClosest entity and distance helpers, teleport
gameClientSpawn and delete vehicles and objects, closest player, ped mugshots
interactionsClientShared "Interact" key (E by default) with conditional handlers
isEnhancedSharedDetects the GTA V Enhanced build
markerZoneClientMarker plus interaction zone built on points
mathSharedClamp, rounding, conversion, lerp, color and heading helpers
medalClientTrigger a Medal.tv clip through the local Medal client
nuiClientSendNUIMessage, focus and NUI callback helpers
onesyncServerPlayers and entities in an area (server-side OneSync)
overloadSharedType-based function overloading
playerServerPlayer ped, coords and distance checks
point / pointsClientProximity points with enter, leave and inside
pubsubClient, ServerServer-driven topic subscriptions
rateLimiterServerToken bucket rate limiter
raycastClientRaycasts from the camera
requireSharedModule loader, xLib.load and xLib.loadJson
scaleformClientFreemode messages, breaking news, popup warnings
schemaServerDatabase column inspection and safe migrations (oxmysql)
serverServerAliases for player distance checks
streamingClientRequest models, dicts, assets with timeout
stringSharedCase conversion, safe matching, randomHex, uuid
tableSharedArray and table helpers
timeoutSharedCancellable setTimeout and clearTimeout
tokenServerSingle-use, expiring tokens
validationShared, ServerValidate numbers, money, strings and player proximity
vehiclePlateSharedNormalize, compare and generate plates
verifySharedRuntime type checks
waitForSharedYield until a function returns a value

The catalog folder is not a regular module. es_extended loads imports/catalog/bootstrap.lua directly (see SQL catalog).

Callbacks

xLib.callback is the callback system ESX uses internally. ESX.TriggerServerCallback and ESX.RegisterServerCallback are compat wrappers around it (xLib.callback.registerCompat). For new code, use xLib directly or the ESX wrappers described in Callbacks.

xLib.callback.register

xLib.callback.register(name, cb)
NameTypeDescription
namestringUnique callback name (max 200 chars). A name owned by another resource raises an error.
cbfunctionServer: function(source, ...). Client: function(...). Its return values are sent back.

Errors inside cb are printed with a stack trace and the caller receives false.

xLib.callback.await

-- client
local ... = xLib.callback.await(name, delay, ...)
-- server
local ... = xLib.callback.await(name, playerId, ...)
NameTypeDescription
namestringCallback name registered on the other side
delaynumber or falseClient only. Throttle in ms: further calls to the same name within this window return immediately without a request.
playerIdnumberServer only. Target player
...anyArguments passed to the handler

Yields the current thread and returns the handler's return values. Rejects with callback '<name>' does not exist if nothing is registered, or with a timeout error.

xLib.callback (with function)

xLib.callback(name, delayOrPlayerId, cb, ...)

Same as await, but calls cb(...) with the results instead of yielding. Omitting cb prints a warning and falls back to await.

server/main.lua
xLib.callback.register('myshop:getBalance', function(source, account)
    local xPlayer = ESX.GetPlayerFromId(source)
    if not xPlayer then return false end

    return xPlayer.getAccount(account).money
end)

xLib.callback.registerCompat

xLib.callback.registerCompat(name, cb, owner)

Registers a handler with the legacy ESX signature: server function(source, cb, ...), client function(cb, ...). owner is the resource whose stop removes the handler. es_extended uses this for ESX.RegisterServerCallback and ESX.RegisterClientCallback.

Callback limits

Server callbacks are protected by per-player budgets. When a player exceeds them, the request is answered with false. All values are server convars.

ConvarDefaultMeaning
xLib:callbackTimeoutfalls back to esx:callbackTimeout, then 300000 msAwait timeout. Replicated to clients when set.
xLib:callbackBurst60Request bucket capacity per player
xLib:callbackRate30Requests refilled per second
xLib:callbackByteBurst262144Payload byte bucket per player
xLib:callbackByteRate65536Bytes refilled per second
xLib:callbackMaxPayloadBytes65536Max packed size of one request
xLib:callbackMaxInFlight8Concurrent callbacks per player
xLib:callbackMaxGlobalInFlight4096Concurrent callbacks server-wide
xLib:callbackValidationGrace15000Delay before an unknown callback name is rejected (capped at half the timeout)
xLib:callbackValidationWindow5000Window for counting invalid-name validations
xLib:callbackValidationMaxRequests30Max invalid-name validations per window

The server-side receiver also gives up after the configured timeout, or 30 seconds when none is set. Payloads are limited to 32 arguments, 2048 entries and 8 levels of nesting.

Client cache

local cache = xLib.cache
KeyTypeDescription
playerIdnumberPlayerId()
serverIdnumberGetPlayerServerId(PlayerId()), resolved lazily
pednumberCurrent player ped
vehiclenumber or falseCurrent vehicle
seatnumber or falseSeat index (-1 is the driver)
weaponnumber or falseSelected weapon hash, false when unarmed
coordsvector3Read live on every access

esx_lib polls every 100 ms and triggers a local event xLib:cache:<key> with (value, previous) when ped, vehicle, seat or weapon change. Other resources update their copy from that event.

client/main.lua
AddEventHandler('xLib:cache:vehicle', function(vehicle, previous)
    if vehicle then
        print('Entered vehicle', vehicle, 'seat', xLib.cache.seat)
    else
        print('Left vehicle', previous)
    end
end)

Points and marker zones

xLib.points.create

local handle = xLib.points.create(coords, distance, hidden, enter, leave, inside)
NameTypeDescription
coordsvector3Point position
distancenumberRadius that counts as "nearby"
hiddenboolean?Hidden points never trigger
enterfunctionCalled once when the player enters the radius
leavefunctionCalled once when the player leaves
insidefunction?Called every frame while nearby, with the current distance

Also available: xLib.points.remove(handle) and xLib.points.hide(handle, hidden). Proximity is scanned every 500 ms; the loop only runs every frame while at least one point with inside is active. Points are removed automatically when the creating resource stops.

xLib.point is the class form: xLib.point:new({ coords, distance, hidden, enter, leave, inside }) with methods :delete() and :toggle(hidden?). Its callbacks receive self.

xLib.markerZone.create

local zone = xLib.markerZone.create(data)
FieldTypeDescription
coordsvector3 or tableZone center
drawDistancenumber?Marker draw radius (alias distance), default 10.0
interactDistancenumber?Interaction radius (aliases actionDistance, enterDistance), default 1.5
exitDistancenumber?Radius to leave interaction, defaults to interactDistance
markertable or falseMarker options, false disables drawing
hiddenboolean?Start hidden
canDraw / canInteractfunction(distance)?Extra conditions
onEnter / onInside / onExitfunction(distance)?Interaction radius handlers
onEnterPoint / onExitPointfunction?Draw radius handlers

Returns { handle, remove(), hide(hidden?), show() }, or nil when coords is invalid.

client/main.lua
local zone = xLib.markerZone.create({
    coords = vector3(25.7, -1347.3, 29.5),
    interactDistance = 1.5,
    onEnter = function()
        ESX.TextUI('[E] Open shop')
    end,
    onExit = function()
        ESX.HideUI()
    end,
})

Interactions and keybinds

xLib.addKeybind

local keybind = xLib.addKeybind(data)
FieldTypeDescription
namestringCommand name (registered as +name / -name)
descriptionstringLabel in the FiveM key bindings menu
defaultMapperstring?Input mapper, default keyboard
defaultKeystring?Default key
disabledboolean?Start disabled
onPressed / onReleasedfunction(self)?Handlers, skipped while the pause menu is open

The returned object has currentKey, isPressed, getCurrentKey(), isControlPressed(), disable(toggle) and remove().

xLib.interactions

esx_lib registers one keybind named esx_interact (default E) and triggers the local event xLib:interact when it is pressed. xLib.interactions lets many resources share that key:

xLib.interactions.register(name, onPress, condition)
xLib.interactions.remove(name)
local key = xLib.interactions.getInteractKey() -- e.g. "E"

Every registered interaction whose condition() returns true runs onPress(). Interactions are removed when their resource stops.

NUI helpers

FunctionDescription
xLib.nui.send(message, data?)Sends a table as-is, or { action = message, data = data } when message is a string
xLib.nui.focus(hasFocus, hasCursor?, keepInput?)SetNuiFocus; cursor defaults to hasFocus
xLib.nui.open(message?, focus?, cursor?, keepInput?)Send and focus (skip focus with focus = false)
xLib.nui.close(message?)Send and drop focus
xLib.nui.ok(data?) / xLib.nui.fail(error, code?)Build { ok, data } / { ok = false, error, code } responses
xLib.nui.register(name, handler)RegisterNUICallback wrapper with error handling

handler(data, reply) can return a value (sent as response, nil becomes ok()), or call reply(response) later. Handlers that declare two parameters and return nil are treated as deferred; they time out after xLib:nuiDeferTimeout ms (default 10000) and reply fail('timeout', 'timeout').

Streaming

All functions accept an optional cb. Without it they yield and return the loaded asset; with it they call cb(asset). Requests time out after xLib:streamingTimeout ms (default 10000).

FunctionReturns
xLib.streaming.requestModel(modelHash, cb?)Model hash or nil
xLib.streaming.requestModelWithSpinner(modelHash, message?, cb?)Model hash or nil
xLib.streaming.requestStreamedTextureDict(textureDict, cb?)Dict name
xLib.streaming.requestNamedPtfxAsset(assetName, cb?)Asset name
xLib.streaming.requestAnimSet(animSet, cb?)Anim set
xLib.streaming.requestAnimDict(animDict, cb?)Anim dict
xLib.streaming.requestWeaponAsset(weaponHash, cb?)Weapon hash
xLib.streaming.requestAudioBank(bankName, cb?)Bank name

Game and entity helpers (client)

FunctionDescription
xLib.game.spawnVehicle(model, coords, heading, cb?, networked?)Spawns a vehicle (networked by default). Yields and returns the handle when cb is omitted. Errors if coords is more than 424 units from the player.
xLib.game.spawnLocalVehicle(model, coords, heading, cb?)Non-networked vehicle
xLib.game.spawnObject(model, coords, cb?, networked?)Spawns an object
xLib.game.spawnLocalObject(model, coords, cb?)Non-networked object
xLib.game.deleteVehicle(vehicle) / deleteObject(object)Deletes the entity
xLib.game.isVehicleEmpty(vehicle)true when no ped is inside
xLib.game.getPeds(onlyOtherPeds?) / getVehicles() / getObjects()Entity pools
xLib.game.getPlayers(onlyOtherPlayers?, returnKeyValue?, returnPeds?)Active players
xLib.game.getClosestPlayer(coords?) / getClosestPed(coords?, modelFilter?) / getClosestObject(coords?, modelFilter?) / getClosestVehicle(coords?, modelFilter?)Returns entity, distance
xLib.game.getPlayersInArea(coords, maxDistance) / getVehiclesInArea(coords, maxDistance)Entities in a radius
xLib.game.isSpawnPointClear(coords, maxDistance)true when no vehicle is in the radius
xLib.game.getVehicleInDirection()Vehicle in front of the player
xLib.game.getVehicleProperties(vehicle) / setVehicleProperties(vehicle, props)Read and apply vehicle mods, colors, extras
xLib.game.getPedMugshot(ped, transparent?)Returns headshot handle and txd string
xLib.entity.closest(entities, isPlayerEntities, coords?, modelFilter?)Closest entity and distance
xLib.entity.EnumerateWithinDistance(entities, isPlayerEntities, coords?, maxDistance)Entities within distance
xLib.entity.Teleport(entity, coords, cb?)Teleports and waits for collision

The ESX.Game.* client functions in es_extended are direct aliases of these (ESX.Game.SpawnVehicle = xLib.game.spawnVehicle and so on). See ESX.Game.

Server player and OneSync helpers

source may be a number or numeric string. Functions return nil (or false) for invalid or disconnected players instead of erroring.

FunctionReturns
xLib.player.getPed(source)Ped or nil
xLib.player.getCoords(source)vector3 or nil
xLib.player.distanceToCoords(source, coords)Distance or nil
xLib.player.isNearCoords(source, coords, distance)nearby, actualDistance
xLib.player.distanceToPlayer(source, target)Distance or nil
xLib.player.isNearPlayer(source, target, distance)nearby, actualDistance
xLib.player.findNearbyCoords(source, coordsList, distance)coords, index, actualDistance
xLib.player.isNearAnyCoords(source, coordsList, distance)nearby, index, actualDistance
xLib.onesync.getPlayersInArea(source, maxDistance, ignore?, routingBucket?)Players near a player id or vector3
xLib.onesync.getClosestPlayer(source, maxDistance, ignore?, routingBucket?)Closest player
xLib.onesync.getPedsInArea / getObjectsInArea / getVehiclesInArea(coords, maxDistance, modelFilter?)Entities in area
xLib.onesync.getClosestPed / getClosestObject / getClosestVehicle(coords, modelFilter?)entity, distance, coords

xLib.server.* (getPlayerCoords, distanceToCoords, isPlayerNearCoords, distanceToPlayer, isPlayerNearPlayer, isPlayerNearAnyCoords) and xLib.validation.playerNearCoords / playerNearPlayer are aliases of the same checks. Use them to validate client requests, for example that a player is actually standing at a shop before you charge them:

server/main.lua
local SHOP <const> = vector3(25.7, -1347.3, 29.5)

xLib.callback.register('myshop:buy', function(source, item)
    if not xLib.player.isNearCoords(source, SHOP, 5.0) then
        return false
    end

    -- process purchase
    return true
end)

Validation and type checks

xLib.validation (shared)

FunctionReturns
xLib.validation.number(value, min?, max?, round?)Finite number in range, else nil
xLib.validation.integer(value, min?, max?, mode?)Integer (mode: round, floor, ceil), else nil
xLib.validation.count(value, max?)Positive item count, else nil
xLib.validation.money(value, min?, max?)Rounded non-negative amount, else nil
xLib.validation.string(value, options?)Trimmed string, else nil. Options: trim, allowEmpty, minLength, maxLength, pattern
xLib.validation.oneOf(value, values)true when value is in the array
xLib.validation.player(source)Server only. true for a connected player
server/main.lua
RegisterNetEvent('myshop:deposit', function(amount)
    local value = xLib.validation.money(amount, 1, 1000000)
    if not value then return end

    local xPlayer = ESX.GetPlayerFromId(source)
    if xPlayer and xPlayer.getMoney() >= value then
        xPlayer.removeMoney(value, 'Shop deposit')
        xPlayer.addAccountMoney('bank', value, 'Shop deposit')
    end
end)

xLib.verify

local ok = xLib.verify(value, types, throwError)

Checks value against one type or an array of types and returns a boolean, or raises an error when throwError is true. Supported types: Lua types plus array, int, uint, float, char, vector3, vector4, ped, vehicle, prop, playerId, class and model. On the server, model asks a random connected client to validate the model through the xLib:validateModel callback. xLib.verify.debug(...) only runs when the xLib:debug convar is true.

Rate limiter and tokens (server)

xLib.rateLimiter

local limiter = xLib.rateLimiter(options)
OptionTypeDescription
capacitynumberMax tokens per key
refillnumberTokens restored per interval
intervalnumberInterval in ms
maxEntriesnumber?Max tracked keys (convar xLib:rateLimiterMaxEntries, default 4096)
staleMsnumber?Idle time before a full bucket is pruned
pruneIntervalnumber?Min time between prunes

Methods: limiter:consume(key, cost?) returns allowed, retryAfterMs; limiter:retryAfter(key, cost?), limiter:reset(key), limiter:clear(), limiter:size(). Buckets keyed by a player id are reset on playerDropped.

server/main.lua
local limiter = xLib.rateLimiter({ capacity = 5, refill = 1, interval = 2000 })

RegisterNetEvent('myjob:search', function()
    local allowed, retryAfter = limiter:consume(source)
    if not allowed then
        return TriggerClientEvent('esx:showNotification', source, ('Wait %d s'):format(math.ceil(retryAfter / 1000)), 'error')
    end
    -- handle search
end)

xLib.token

FunctionDescription
xLib.token.create({ source?, ttl, data? })Returns a token id. ttl in ms (default 30000). Max entries via xLib:tokenMaxEntries (default 4096).
xLib.token.consume(id, source?)Returns data once; the token is deleted. Fails if source does not match.
xLib.token.remove(id)Deletes a token
xLib.token.reset(source)Deletes all tokens of a player, returns count
xLib.token.clear() / xLib.token.size()Clear all / count

Tokens of a player are removed on playerDropped.

Pub/sub

The server subscribes players to topics and publishes data only to them. Clients can only listen. Topic names must match ^[%w_:%.%-]+$ (max 200 chars); prefix them with your resource name.

FunctionSideDescription
xLib.pubsub.subscribe(src, topic)ServerReturns true if added
xLib.pubsub.unsubscribe(src, topic)ServerReturns true if removed
xLib.pubsub.publish(topic, data)ServerSends to all subscribers, returns the count
xLib.pubsub.subscribers(topic)ServerArray of server ids
xLib.pubsub.isSubscribed(src, topic)ServerBoolean
xLib.pubsub.clear(topic)ServerDrops the topic, returns removed count
xLib.pubsub.on(topic, handler)Clienthandler(data, topic)
xLib.pubsub.off(topic, handler?)ClientRemoves one or all handlers

Players are removed from all topics on disconnect, and topics are cleared when the resource that created them stops.

server/main.lua
local TOPIC <const> = 'myshop:247:stock'

RegisterNetEvent('myshop:openShop', function()
    xLib.pubsub.subscribe(source, TOPIC)
end)

local function updateStock(stock)
    xLib.pubsub.publish(TOPIC, stock)
end

Shared utilities

Table, string and math

xLib.table: isArray, searchForKey, filter, deepcopy, merge, dump, sizeOf, set, indexOf, lastIndexOf, find, findIndex, map, reverse, clone, concat, join, contains, sort (sorted pairs iterator), toArray, wipe. The ESX.Table.* functions are direct aliases, see ESX.Table.

xLib.string: normalize, capitalize, toSnake, toCamel, toPascal, escapePattern, matchSafe, before, after, contains, replace, randomHex(length), uuid().

xLib.math: clamp, toNumber, tryNumber, toInteger, toScalars, toVector, normalToRotation, toRGBA, hexToRGBA, toHex, groupDigits, round, interpolate, lerp, inverseLerp, remap, plus the ESX-style Round, GroupDigits, Trim, Random, GetHeadingFromCoords used by ESX.Math.

Timeout and waitFor

local id = xLib.timeout.setTimeout(msec, cb)
xLib.timeout.clearTimeout(id)

local value = xLib.waitFor(cb, errMessage, timeout, interval)

waitFor calls cb until it returns a non-nil value. It errors after timeout ms (default 5000; pass false to wait forever) and polls every interval ms (default 0). ESX.SetTimeout, ESX.ClearTimeout and ESX.Await are aliases. See Timeout.

client/main.lua
local vehicle = xLib.waitFor(function()
    local veh = GetVehiclePedIsIn(PlayerPedId(), false)
    if veh ~= 0 then return veh end
end, 'Player never entered a vehicle', 10000)

Vehicle plates

FunctionDescription
xLib.vehiclePlate.normalize(plate, options?)Trimmed, normalized plate or nil. Options: maxLength, uppercase, compact, allowEmpty, pattern, coerce
xLib.vehiclePlate.equals(left, right, options?)Compares two plates after normalizing
xLib.vehiclePlate.matchesVehicle(vehicle, plate, options?)Compares against a vehicle's plate
xLib.vehiclePlate.generate(options?)Random plate. Options: prefix, suffix, letters (3), numbers (3), useSpace
xLib.vehiclePlate.generateUnique(options?, exists?)Retries up to options.attempts (30) until exists(plate) returns false; reserves the plate for 30 s
xLib.vehiclePlate.randomLetters(length) / randomNumbers(length)Random chunks

Other shared modules

  • xLib.class(copy?) creates a class; instances are made with Class:new(...), which calls constructor.
  • xLib.overload(name, validTypes, cb, obj?) registers a typed overload, dispatched by argument types.
  • xLib.isEnhanced() returns true on the GTA V Enhanced build (server: gamename convar gta5enhanced or gta5_enhanced).
  • xLib.colors exposes brand, darkest, dark, mid, light, lightest and getESXTheme(defaults?). See convars.

require, load and loadJson

local config = require 'config.shops'        -- loads config/shops.lua from your resource
local other  = require '@other_resource.data' -- loads data.lua from another resource
local result = xLib.load('scripts/once')     -- runs a file without caching
local data   = xLib.loadJson('data/items')   -- decodes data/items.json

Dots become slashes. Search paths are ./?.lua and ./?/init.lua. The file must be listed in the target resource's files or scripts so LoadResourceFile can read it on the client. Circular requires raise an error.

Other client modules

  • xLib.blips.create(data), xLib.blips.createMany(items, defaults?), xLib.blips.remove(blip). data can be a vector3 or a table with coords or entity or radius, plus sprite, display, scale, color, alpha, shortRange, label, route, routeColor and more.
  • xLib.dui:new({ url, width, height, debug? }) with remove(), setUrl(url), sendMessage(message), sendMouseMove(x, y), sendMouseDown(button), sendMouseUp(button), sendMouseWheel(deltaX, deltaY). DUIs are destroyed when the resource stops.
  • xLib.scaleform.showFreemodeMessage(title, msg, sec), showBreakingNews(title, msg, bottom, sec), showPopupWarning(title, msg, bottom, sec), showTrafficMovie(sec), plus xLib.scaleform.utils.requestScaleformMovie(movie) and runMethod(scaleform, methodName, returnValue?, ...).
  • xLib.Raycast.FromScreen(depth, ...), xLib.Raycast.Start(depth, ...), xLib.Raycast:Stop(), xLib.Raycast:IsActive(), xLib.Raycast.GetShapeTestResult(shape).
  • xLib.medal.triggerClip(publicKey?, eventName?, clipOptions?) and xLib.medal.getConfig().

Server-only modules

  • xLib.schema (needs oxmysql): column(tableName, columnName), identifier(value), ensureColumn(tableName, columnName, definition), widenVarchar(tableName, columnName, length, column?), ensureProperty(), ensureMileage(). es_extended migrations and esx_multicharacter use it to adjust tables safely.
  • xLib.triggerClientEvent(eventName, targets, ...): targets is one server id or an array. For arrays, the payload is packed once and sent to each client, which is cheaper than calling TriggerClientEvent in a loop.

SQL catalog

imports/catalog/bootstrap.lua is loaded as a server script by es_extended, esx_identity, esx_multicharacter and esx_skin. On start it reads imports/catalog/data.json (catalog version 1.16.0) and creates missing tables, columns and seed rows (jobs, items, licenses, vehicles and more) for ESX core and official addons, using the locale from Config.SqlCatalogLocale, Config.Locale or the esx:locale convar. Other resources call the es_extended export EnsureSqlCatalog(name, locale), which only lets a resource prepare its own catalog. When done, it triggers the server event esx:sqlCatalogReady with the list of touched catalogs. If it fails, resource initialization is blocked and the console prints SQL catalog FAILED.

Exports

Functions defined in esx_lib's own resource/ scripts are exported automatically. You normally reach them through xLib, but they are callable as exports.esx_lib:<name>(...):

ExportSideDescription
setValidCallback(name, isValid, owner?)BothInternal callback ownership registry
isCallbackValid(name)Bothtrue if a callback name is registered
acquireCallbackBudget / releaseCallbackBudget / chargeCallbackBytesServerInternal callback rate budget
pubsub_subscribe, pubsub_unsubscribe, pubsub_publish, pubsub_subscribers, pubsub_isSubscribed, pubsub_clearServerPub/sub registry
triggerClientEvent(eventName, targets, ...)ServerPacked multi-target event
getMedalConfig() / triggerMedalClip(publicKey, eventName, clipOptions)ClientMedal.tv integration

Events

EventSideTypePayload
xLib:cache:<key>ClientLocalvalue, previous for ped, vehicle, seat, weapon
xLib:interactClientLocalFired when the esx_interact key is pressed
xLib:validateCallbackBothNet (internal)Callback validation
esx:sqlCatalogReadyServerLocalcatalogs table, fired by the catalog bootstrap

Configuration

config.lua only configures the Medal.tv integration. esx_lib's NUI page posts clip requests to the Medal desktop client at http://localhost:12665, so nothing happens for players who do not run Medal.

KeyDefaultDescription
Config.Medal.enabledtrueAllow xLib.medal.triggerClip
Config.Medal.publicKeyESX public keyMedal API public key
Config.Medal.eventName'Death'Default event name
Config.Medal.clipOptions.duration30Clip length in seconds
Config.Medal.clipOptions.captureDelayMs0Delay before capture
Config.Medal.clipOptions.alertType'Default'Default, Disabled, SoundOnly or OverlayOnly

Convars

ConvarDefaultDescription
xLib:debugfalseDebug output, enables xLib.verify.debug
xLib:nuiDeferTimeout10000Deferred NUI callback timeout (ms)
xLib:streamingTimeout10000Streaming request timeout (ms)
xLib:rateLimiterMaxEntries4096Default max keys per rate limiter
xLib:tokenMaxEntries4096Max active tokens
esx:brand-color#FB9B04xLib.colors.brand
esx:darkest-color / esx:dark-color / esx:mid-color / esx:light-color / esx:lightest-color#161616 / #252525 / #383838 / #969696 / #F2F2F2Palette
esx:ui:primaryColor, esx:ui:secondaryColor, esx:ui:backgroundColor, esx:ui:accentColor, esx:ui:logoUrlpalette valuesTheme returned by xLib.colors.getESXTheme()

Callback convars are listed in Callback limits.

server.cfg
setr esx:ui:primaryColor "#3B82F6"
set xLib:callbackTimeout 60000

Version reporting

On the server, esx_lib publishes the version and legacyversion metadata of every ESX resource (names starting with esx_ or es_, or that depend on es_extended or esx_lib) as server info convars named <resource>-version. This is what server lists and support tools read to see which ESX version you run. It runs 2 seconds after start and again for each ESX resource that starts later.

Common issues

  • attempt to index a nil value (global 'xLib'): @esx_lib/imports.lua is missing from shared_scripts, or esx_lib is not started.
  • Renamed folder: the loader reads files from a resource literally named esx_lib. Keep the name.
  • callback '<name>' does not exist: the name is not registered on the receiving side, or its resource stopped. On the server this is reported after the validation grace period (up to 15 s).
  • callback '<name>' is already owned by resource '<x>': two resources registered the same callback name. Prefix names with your resource.
  • Callback returns false under load: the player hit a callback budget. Check the callback limits and avoid calling server callbacks every frame; use the client delay argument.
  • require cannot find a file on the client: the file is not in the resource's files list, so LoadResourceFile cannot read it.
  • SQL catalog FAILED: oxmysql is not connected or the database user cannot create or alter tables.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page