Skip to main content
The framework bridge is the piece of TS-Lib that hides the differences between:
  • qb-core (qbcore)
  • qbx_core (qbox)
  • es_extended (esx)
  • a minimal standalone mode
Instead of scattering if framework == 'qbcore' then ... elseif framework == 'esx' ... in your code, you call Bridge.Framework.* and let TS-Lib route to the right implementation.
-- Shared
Bridge.Framework
Bridge.Framework.Client
Bridge.Framework.Server

Status & testing

FrameworkStatusTested by
qbcoreTestedToine
esxTestedToine
qboxExperimentalwaiting for feedback
standaloneTestedToine

How selection works

Supported values in ts-lib/config.lua:
  • Framework keys: qbcore, esx, qbox, standalone
  • Mapped to resource names via Config.Data.Framework:
Config.Data.Framework = {
  qbcore     = 'qb-core',
  esx        = 'es_extended',
  qbox       = 'qbx_core',
  standalone = 'standalone',
}
When Config.Framework = 'auto', TS-Lib goes through this table and picks the first started resource.

Client-side API

Bridge.Framework.Client.PlayerData

Unified player data table populated automatically when the player loads and kept in sync on job changes.
  • QBCore / Qbox: based on QBCore.Functions.GetPlayerData()
  • ESX: based on xPlayer job data where possible
  • Standalone: minimal stub (no job system)

Bridge.Framework.Client.Functions.GetPlayerJob()

local ok, job = Bridge.Framework.Client.Functions.GetPlayerJob()
if ok then
  print(('Job: %s (%s)'):format(job.name, job.label))
else
  print('Error:', job)
end
Returns:
  • true, jobTable on success
  • false, errorMessage if no job is available (for example in standalone)

Bridge.Framework.Client.Functions.Notify(message, type?)

Generic notification helper:
  • QBCore / Qbox: QBCore.Functions.Notify
  • ESX: ESX.ShowNotification or a basic native fallback
  • Standalone: simple native notification
Bridge.Framework.Client.Functions.Notify('Saved vehicle successfully', 'success')

Client events

All supported frameworks fire the same normalized events once the bridge is loaded:
  • ts-lib:client:onPlayerLoaded (playerData)
  • ts-lib:client:onPlayerUnloaded ()
  • ts-lib:client:onJobUpdated (job)
You can listen directly to these events, or use the internal event system:
Bridge.Framework.Client.On('onPlayerLoaded', function(playerData)
  print('Player loaded with job:', playerData.job and playerData.job.name)
end)

Bridge.Framework.Client.On('onJobUpdated', function(job)
  print('Job updated to:', job.name)
end)

Server-side API

Bridge.Framework.Server.Functions.GetPlayerJob(source)

local ok, job = Bridge.Framework.Server.Functions.GetPlayerJob(source)
if not ok then
  return print('Failed to get job:', job)
end

print(('Player %d is %s'):format(source, job.name))

Bridge.Framework.Server.Functions.GetPlayersByJobName(jobName, checkOnDuty?)

local ok, players = Bridge.Framework.Server.Functions.GetPlayersByJobName('police', true)
if ok then
  print(('Found %d on-duty police players'):format(#players))
else
  print('Error:', players)
end

Bridge.Framework.Server.Functions.GetPlayers()

Returns a list of player sources, using the most appropriate method for each framework:
  • QBCore: QBCore.Functions.GetPlayers()
  • Qbox: exports.qbx_core:GetQBPlayers()
  • ESX: ESX.GetPlayers() (or GetPlayers() as a fallback)
  • Standalone: GetPlayers()

Bridge.Framework.Server.Functions.GetVehicleType(model)

local vehicleType = Bridge.Framework.Server.Functions.GetVehicleType(GetHashKey('adder'))
When possible this uses framework-specific shared vehicle tables; otherwise it falls back to 'automobile'.

Server events

Normalized events fired regardless of the underlying framework:
  • ts-lib:server:onPlayerLoaded (source)
  • ts-lib:server:onPlayerUnloaded (source?)
  • ts-lib:server:onJobUpdated (job)
You can also subscribe through the server-side event emitter:
Bridge.Framework.Server.On('onPlayerLoaded', function(source)
  print('Player loaded:', source)
end)

Framework-specific notes

QBCore / Qbox

  • QBCore: exports['qb-core']:GetCoreObject()
  • Qbox: exports['qbx_core']:GetCoreObject() and exports.qbx_core:GetQBPlayers()
Jobs are normalized into a structure similar to:
job = {
  name         = 'police',
  label        = 'Police',
  onduty       = true,
  type         = 'leo',
  grade        = 3,
  grade_name   = 'sergeant',
  grade_label  = 'Sergeant',
  grade_salary = 0,
}

ESX

  • Uses exports['es_extended']:getSharedObject().
  • Bridges try to map ESX job information onto the same keys used by QB-style frameworks.

Standalone

Standalone intentionally keeps a minimal surface:
  • No job system (GetPlayerJob returns an error).
  • GetPlayers() simply wraps the FiveM native.
  • GetVehicleType always returns 'automobile'.
Last modified on March 13, 2026