Quasar Framework (qs-core) runs ESX scripts and QBCore scripts on the same FiveM server, at the same time, without editing them. Two compatibility bridges ship in the [bridge] folder — es_extended and qb-core — and they answer exactly where a script expects the real frameworks to be. Both bridges read and write one shared player: the money an ESX job pays is the money a QBCore shop charges, the job a QBCore script sets is the job an ESX script reads, and an item added with xPlayer.addInventoryItem shows up in Player.PlayerData.items.
Why it matters: the FiveM roleplay market is split in two. A large share of scripts is written for ESX (ESX Legacy, es_extended), another large share for QBCore (qb-core), and choosing a framework used to mean giving up the other half — or paying for conversions and maintaining forks. With Quasar Framework you forget about framework limits and pick scripts for what they do, not for the framework they were written for.
How the ESX and QBCore bridges work#
The [bridge] folder holds seven small resources. Each one takes the name of a well-known FiveM resource and answers its API on top of Quasar Framework:
Resource | Answers as | What it provides |
|---|---|---|
| ESX Legacy (version | The ESX object, |
| QBCore (version | The QBCore object, the |
| esx_society | Society money accounts. |
| qb-management | Job and gang funds. |
| qb-vehiclekeys | Vehicle keys, forwarded to |
| progressbar | Progress bars, drawn by Quasar Framework. |
| LegacyFuel |
|
Both frameworks run at once. server.cfg starts the bridges last, with ensure [bridge] after every [core] and [addons] resource, the character flow and [maps]. es_extended and qb-core each listen to Quasar Framework's own events independently, so neither depends on the other and neither has to be switched on or off.
Because the bridges take the resource names es_extended and qb-core, the real ESX and QBCore cannot run next to them — and they do not need to.
How scripts find ESX and QBCore#
Scripts find the bridges with the same calls they use on a real ESX or QBCore server:
What the script does | Framework | Notes |
|---|---|---|
| ESX | Server and client. The usual way in ESX Legacy. |
| ESX | Older ESX style, server and client. |
| ESX | Sets the global |
| ESX |
|
| QBCore | Server and client. With a filter list, returns only those keys. |
| QBCore | One |
| QBCore | Older QBCore style, server and client. |
| QBCore | The |
| QBCore | Fired after the core object changes ( |
Scripts that support both frameworks and detect them automatically will find both started and use whichever they check first. Either choice works, because both bridges talk to the same player. If the script has a framework setting, you can also set it to ESX or QBCore yourself.
One player, shared by ESX and QBCore#
Quasar Framework keeps one character per player. The bridges do not copy it — they read and write it, so every script sees the same values at the same moment:
Data | ESX script sees | QBCore script sees |
|---|---|---|
Character id |
|
|
Cash |
|
|
Bank | account |
|
Other accounts | any other account name (for example | any other money type (for example |
Job |
|
|
Items |
|
|
Metadata |
|
|
Gang | — |
|
Name, birth date, sex |
|
|
Here is an ESX script that hires a player and pays a signing bonus:
-- server.lua of an ESX script
local ESX = exports['es_extended']:getSharedObject()
RegisterNetEvent('myjob:server:hire', function()
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return end
xPlayer.setJob('police', 1)
xPlayer.addAccountMoney('bank', 2500)
xPlayer.addInventoryItem('repairkit', 1)
end)And a QBCore script on the same server, reading the same character a moment later:
-- server.lua of a QBCore script
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Commands.Add('whoami', 'Show your character', {}, false, function(source)
local Player = QBCore.Functions.GetPlayer(source)
local data = Player.PlayerData
print(data.citizenid) -- the same id ESX sees as xPlayer.identifier
print(data.job.name, data.job.grade.level) -- police 1
print(data.money.bank) -- includes the 2500 the ESX script paid
local kit = Player.Functions.GetItemByName('repairkit')
print(kit and kit.amount) -- 1
end)The events line up too: when the ESX script calls setJob, ESX scripts receive esx:setJob and QBCore scripts receive QBCore:Server:OnJobUpdate from the same change. When it pays the bonus, QBCore scripts receive QBCore:Server:OnMoneyChange.
ESX (es_extended) coverage#
The es_extended bridge reproduces the ESX Legacy API that scripts use day to day. Everything below works on Quasar Framework as it does on ESX; the few functions that exist only as placeholders are listed in What is not covered.
Server: ESX functions#
Players
Function | What it does |
|---|---|
| The |
| Finds an online player by citizenid, or by |
| Server ids of every connected player. |
| Every |
| Number of connected players. |
| The |
Callbacks and commands
Function | What it does |
|---|---|
| Server callback with the ESX signature |
| Chat command (one name or a list). |
Items
Function | What it does |
|---|---|
| Makes an item usable. When a player uses it from the inventory, |
| Runs an item's registered callback. |
| The item catalogue, always current. |
| The catalogue as it was when the bridge started ( |
| The item's label. |
Jobs
Function | What it does |
|---|---|
| Every job in ESX shape, always current: |
| The same table, as it was when the bridge started. |
| Whether a job (and optionally a grade) exists. |
Vehicles
Function | What it does |
|---|---|
| Creates a vehicle on the server and returns its network id (also passed to |
| Deletes a vehicle by network id. |
|
|
Utilities (server and client)
Function | What it does |
|---|---|
| The bridge's config, or one key of it. |
| Number and string helpers. |
| Table helpers. |
| Debug print and cancellable timeouts. |
The bridge also answers two things character scripts rely on: the server callback esx_identity:registerIdentity (creates and loads a character from ESX identity data, then fires esx_identity:completedRegistration) and the server event esx:playerLogout, which logs the character out.
Server: the xPlayer object#
Fields
Field | Value |
|---|---|
| Server id. |
| The character's citizenid. |
| The player's Rockstar license. |
| Character first and last name. |
| ESX job table, refreshed on every job change. |
|
|
| The character's metadata. |
|
|
| Values stored with |
Player
Method | What it does |
|---|---|
| Character first and last name. |
| The citizenid. |
|
|
| Adds the player to |
| Position (table, or |
| Sends a client event to this player. |
| Drops the player. |
| Script variables, saved with the character. |
| Character metadata. |
| Quasar Framework notification. |
| ESX advanced and help notifications. |
Money and accounts
Method | What it does |
|---|---|
| Cash. |
|
|
|
|
Inventory
Method | What it does |
|---|---|
| Items grouped by name: |
|
|
| Through the real inventory, with weight and slots respected. Returns |
| Adds or removes the difference. |
| Weight and space check / ownership check. |
| Whether the player can carry |
| Current carried weight / the ESX maximum weight. |
Job
Method | What it does |
|---|---|
| The current job in ESX shape. |
| Sets the job. A job that does not exist yet is created with grades |
Client: ESX functions#
Area | What you get |
|---|---|
Player data |
|
Callbacks |
|
Notifications |
|
Progress |
|
Menus |
|
Streaming |
|
Game |
|
ESX events#
Event | Side | Arguments | When |
|---|---|---|---|
| server |
| A character is loaded. |
| client |
| A character is loaded. |
| client | — | The character logs out. |
| server |
| A player with a loaded character disconnects. |
| server |
| Job or duty changes. |
| client |
| Job or duty changes. |
| client |
| Cash, bank or |
| client |
| An item count changes. |
| client |
|
|
| client | death data / — | From a once-a-second check of GTA's death state. |
| server |
| After |
The bridge also handles esx:showNotification, esx:showAdvancedNotification and esx:showHelpNotification sent from the server, and esx:triggerServerCallback / esx:serverCallback for callbacks.
QBCore (qb-core) coverage#
The qb-core bridge reproduces the QBCore API. QBCore.Functions.GetPlayer rebuilds PlayerData from Quasar Framework on every call, so each call returns the current balance, job and items.
Server: QBCore.Functions#
Players
Function | What it does |
|---|---|
| The |
| An online player by citizenid. |
| An offline character, read from the database: |
| Server ids / |
| Players of a job that are on duty, and how many. |
Callbacks
Function | What it does |
|---|---|
| Server callback with the QBCore signature |
| Calls a client callback registered with |
Items
Function | What it does |
|---|---|
| Makes an item usable; |
| Looks up / runs a usable item callback. |
| Accepts one name, a list of names, or |
Identity and permissions
Function | What it does |
|---|---|
| A FiveM identifier ( |
| Server id from a FiveM identifier or a citizenid ( |
|
|
| Grant, revoke and list permissions. |
| Checks Quasar Framework's ban list. |
| Drops the player. |
Shared data and extensions
Function | What it does |
|---|---|
| Change |
| The same for items. |
| The same for gangs. |
| Extend one player, several, or all of them ( |
| Extend |
| Notification to a player. |
|
|
| Server-side vehicle; returns its network id. Also exported as |
|
|
Server exports: GetCoreObject, GetShared, SetMethod, SetField, AddJob, AddJobs, RemoveJob, UpdateJob, AddItem, AddItems, UpdateItem, RemoveItem, AddGang, AddGangs, RemoveGang, UpdateGang, GetCoreVersion, ExploitBan (permanent ban) and SpawnVehicle.
Commands#
Function | What it does |
|---|---|
| Registers a chat command with its suggestion. |
| Re-sends the command suggestions to a player (done automatically when a character loads). |
Server: the Player object#
Player.PlayerData holds source, citizenid, license, name, money (cash, bank, crypto), charinfo (firstname, lastname, birthdate, gender, nationality, phone, account), job, gang, metadata (the character's metadata over the QBCore defaults: hunger, thirst, stress, isdead, inlaststand, armor, ishandcuffed, callsign, licences, jobrep and the rest), position (vector4) and items (QBCore slot shape).
Method | What it does |
|---|---|
|
|
| Through the real inventory, with |
| Changes one key of an item's |
| Items in QBCore slot shape ( |
| Empties the inventory. |
| Character metadata. |
| Sets the job. A job that does not exist yet is created from |
| Sets the gang. |
| Sets the duty flag and tells the client. |
| Writes |
| Adds to |
| Notification to this player. |
| Saves the character now. |
| Extend this player object. |
Shared tables#
Table | Content |
|---|---|
| On the server: every item of Quasar Framework in QBCore shape ( |
| On the server: every job, grades in QBCore shape ( |
| Gangs from |
| 106 GTA weapons keyed by hash. |
Helpers |
|
QBCore.Config is there for scripts that read it (MaxPlayers follows sv_maxclients). The values that actually shape the server — starting money, paychecks, autosave — come from Quasar Framework's own config. See Configuration.
Client: QBCore.Functions#
Function | What it does |
|---|---|
|
|
| Calls a server callback. |
| A callback the server can call with |
| Quasar Framework notification ( |
| Quasar Framework progress bar with the animation and one prop. |
| Whether the player has the item(s). |
| World queries. |
| Streaming. |
| Vehicles. |
| Drawing and checks. |
QBCore.PlayerData is filled when the character loads and kept current by the events below; LocalPlayer.state.isLoggedIn is set to true on load.
QBCore events#
Event | Side | Arguments | When |
|---|---|---|---|
| server |
| A character is loaded. |
| client | — | A character is loaded. |
| server |
| A player disconnects. |
| server |
| The job changes. |
| client |
| The job changes. |
| server |
| Money is added or removed. |
| client |
| Money is added or removed. |
| server / client |
| The gang changes. |
| client |
| Duty changes. |
| server |
| A player toggles duty with |
| client |
| After every change to the player. |
| client |
| Items, jobs or gangs added or changed at runtime. |
The bridge also handles QBCore:Notify and QBCore:Client:Notify on the client, and QBCore:ToggleDuty, QBCore:Server:SetMetaData (hunger, thirst, stress) and the callback events on the server.
Ecosystem bridges: society, keys, progress and fuel#
Many ESX and QBCore scripts also call a handful of popular companion resources. Five of them are answered by small bridges:
Bridge | What scripts call | What answers |
|---|---|---|
| Server exports | Society accounts kept in memory and saved to the |
| Server exports | Funds saved to the |
| Client exports | Quasar Framework's vehicle keys ( |
| Client exports | Quasar Framework's progress bar, with the animation, props and movement lock from |
| Client exports | Fuel kept on the vehicle (0–100) and consumed while the engine runs, faster at high RPM; the engine stops at 0. The HUD fuel gauge reads it. |
ESX ESX.Progressbar and QBCore QBCore.Functions.Progressbar use the same progress bar. How each of these connects to the rest of the server is in Integrations.
Database compatibility#
Quasar Framework stores characters in its own players table. The bridges add the ESX and QBCore tables scripts query most, so their SQL keeps working where it can:
Table | Created by | What it holds |
|---|---|---|
| Quasar Framework ( | One row per character: |
|
| The ESX view of each character, keyed by citizenid: |
| Quasar Framework | Owned vehicles: |
|
| Created with the ESX columns so queries do not fail; Quasar Framework vehicles live in |
|
|
|
|
|
|
For vehicle lists, scripts can call exports['qs-core']:GetCitizenVehicles(citizenid) (every row of vehicles for a character) or exports['qs-core']:GetPlayerVehiclesQBShape(citizenid) (the same rows in QBCore player_vehicles shape).
Adding an ESX or QBCore script#
Install what the script depends on
Read the script's requirements and install its dependencies as they are.
oxmysqlandox_libare already installed. Target, menu and input resources —ox_target,qb-targetwithPolyZone,qb-menu,qb-input, or an ESX menu such asesx_menu_defaultforESX.UI.Menu— go in as the script's own documentation says. Do not installes_extended,qb-coreor the other names in[bridge]: the bridges already are those resources.Put the script in your resources folder
Copy the script's folder anywhere under
resources, for example in a[scripts]folder of your own. Leave the script's code as it is.Start it after the bridges
In
server.cfg,ensurethe script and its dependencies afterensure [bridge]:bash ensure [bridge] # Third-party scripts ensure PolyZone ensure qb-target ensure my-qbcore-script ensure my-esx-scriptScripts that start before
[bridge]cannot findes_extendedorqb-core.Import its SQL
If the script ships an
.sqlfile for its own tables, import it into your database. ESX scripts often also insert rows into ESX'sitems,jobsandjob_gradestables: Quasar Framework does not read those tables, so add the same items and jobs in the next two steps instead. If the file adds columns tousers, remember thatusersis written from Quasar Framework and is not read back (see Database compatibility).Add its items
Every item the script gives or checks must exist in the item catalogue —
getInventoryItemreturnsnilfor an item that does not exist, and an inventory cannot hold it. Use whichever format the script ships; weights are in grams:Add the items to the
basetable in[core]/qs-core/shared/items.lua:lua local base = { -- ...existing items... fishing_rod = { label = 'Fishing Rod', weight = 1500, useable = true, description = 'For the lake.' }, raw_fish = { label = 'Raw Fish', weight = 400, useable = false }, }Add them to
BridgeItemsin[bridge]/es_extended/config/items.lua. They are created in Quasar Framework when the server starts (fieldslabel,weight,useable,description,unique,image):lua BridgeItems = { fishing_rod = { label = 'Fishing Rod', weight = 1500, useable = true }, raw_fish = { label = 'Raw Fish', weight = 400 }, }Paste the script's QBCore item entries into
[bridge]/qb-core/shared/items.lua. They are registered in Quasar Framework when the server starts, and they are also available to the script on the client:lua QBCore.Shared.Items = { fishing_rod = { name = 'fishing_rod', label = 'Fishing Rod', weight = 1500, type = 'item', image = 'fishing_rod.png', unique = false, useable = true, shouldClose = true, description = 'For the lake.' }, }Add its jobs and gangs
Add the jobs the script uses to
[core]/qs-core/shared/jobs.lua, or paste the QBCore job entries into[bridge]/qb-core/shared/jobs.lua. A job a script sets that exists nowhere is created on the fly with generic grades and no salary (ESX: grades0–3, QBCore:0–4), so defining it yourself gives it the right labels and pay. QBCore gangs go in[bridge]/qb-core/shared/gangs.lua.A job in
[core]/qs-core/shared/jobs.lua, inside theJobstable:lua ['mechanic'] = { label = 'Mechanic', defaultDuty = true, grades = { [0] = { name = 'trainee', label = 'Trainee', salary = 300 }, [1] = { name = 'mechanic', label = 'Mechanic', salary = 500 }, [2] = { name = 'boss', label = 'Owner', salary = 900, isBoss = true }, }, },Restart and test
Restart the server so the catalogue is read again. In game, give yourself the script's items and job with the admin commands —
/giveitem <id> <item> [count]and/setjob <id> <job> [grade]— and try every feature. Keep the server console and the F8 console open: the ESX bridge prints a warning when a script calls a server callback that nobody registered.
Writing your own resource? You can call ESX or QBCore functions as shown on this page, or Quasar Framework's own exports directly. See Commands and Exports.
What is not covered#
The bridges cover the API that ESX and QBCore scripts use in practice. These parts are outside it:
Qbox-only scripts. Scripts written only for Qbox (
qbx_core) are not supported. Scripts that support QBCore run through theqb-corebridge.Direct inventory exports. Scripts that call
exports['qb-inventory']orexports['ox_inventory']directly are not covered. Items, stashes and usable items go through the framework functions above.Raw SQL on character tables. Writes to
usersare not read back. Queries onplayerssee Quasar Framework's JSON shapes, and a change written to an online character is replaced by the next autosave.Vehicle tables of ESX and QBCore.
player_vehicles(QBCore) is not created andowned_vehicles(ESX) stays empty, so garage or dealership scripts that read those tables with SQL do not see Quasar Framework vehicles. Use the built-in garages and dealership, or the vehicle exports above.ESX weapon loadouts. Weapons in Quasar Framework are inventory items (
weapon_pistol...).xPlayer.getLoadout()returns{},hasWeapon()returnsfalse,getWeapon()returnsniland weapon components and tints are not implemented.xPlayer.addWeapon()gives a GTA weapon that is not an inventory item and is not saved; give the weapon item withaddInventoryIteminstead.ESX placeholders.
ESX.CreatePickupdoes nothing (it prints a warning).ESX.SavePlayerandESX.SavePlayersonly run their callback — Quasar Framework saves on its own.ESX.UI.HUDfunctions do nothing andESX.Scaleformis empty.xPlayer.setName()does nothing,xPlayer.setGroup()lasts for the session only (use/setgroupto keep a group), and thexPlayer.groupfield readsuser— usexPlayer.getGroup().ESX weight.
xPlayer.getMaxWeight()returns 24000, fromConfig.MaxWeight = 24in[bridge]/es_extended/shared/config/main.lua, while the inventory's own limit is 50 kg.canCarryItemchecks the real limit; setConfig.MaxWeight = 50if a script compares weights itself.ESX functions not present.
ESX.GetWeapon,ESX.GetWeaponList,ESX.GetWeaponLabel, client callbacks (ESX.TriggerClientCallback), await-style callbacks,ESX.TextUI/ESX.HideUI, theESX.OpenContextfamily,ESX.SearchInventoryandESX.OneSynchelpers other thanSpawnVehicle/DeleteVehicle. Vehicle properties passed toESX.OneSync.SpawnVehicleare stored on the vehicle but not applied. OnxPlayer:hasWeaponComponent,setWeaponTint,getWeaponTint,updateWeaponAmmo,updateCoords,syncInventory.QBCore functions not present. Return-value (await)
TriggerCallback, routing bucket functions,CreateVehicle/CreateAutomobile,ToggleOptin,IsWhitelisted,IsLicenseInUse,PrepForSQL;Player.Functions.Logout,SetInventory,AddRep/RemoveRep/GetRep,SetCreditCard,GetCardSlot;QBCore.Player.Login,Logout,CreatePlayer,Save.QBCore.Player.SaveOfflinedoes nothing — use theSavefunction of the offline player object.QBCore.Shared.Vehiclesis empty.QBCore events not emitted.
QBCore:Client:OnPlayerUnloadandQBCore:Client:OnMoneyChange;QBCore:Server:OnPlayerUnloadfires on disconnect, not on/logout.QBCore character details.
cidis always1, and characters have no phone number of their own (charinfo.phonereads0000000000). On the client,QBCore.PlayerData.metadataholds the character's metadata without the QBCore default keys, which are only added on the server.ESX add-on resources.
esx_addonaccount,esx_datastoreandesx_addoninventoryare not provided, and neitheresx_societynorqb-managementincludes a boss menu.
Frequently asked questions#
Can I run ESX and QBCore scripts on the same FiveM server?
Yes — that is what Quasar Framework is built for. The es_extended and qb-core bridges run together and both talk to the same player, so an ESX script and a QBCore script share the same money, job, items and metadata.
Do I need to edit my ESX or QBCore scripts?
No. Scripts that use the framework object, its callbacks, its events and its usual helpers run as they are. What you do once per script is add its items and jobs to the catalogue and start it after [bridge].
Do I still need to convert ESX scripts to QBCore, or QBCore scripts to ESX?
No. ESX to QBCore conversion — and QBCore to ESX — is no longer needed: each script runs on the bridge for the framework it was written for, and both bridges share one player.
Does it work with Qbox?
Scripts that support QBCore work through the qb-core bridge, including many that also support Qbox. Scripts written only for Qbox (qbx_core) are not supported.
Can I use ox_inventory?
No. Quasar Framework's inventory is qs-coreinventory, or Quasar Store's advanced qs-inventory (see Integrations). Scripts that call ox_inventory exports directly are not covered; if a script lets you choose its inventory, choose the ESX or QBCore option so it goes through the bridge.
Should I install esx_identity, esx_multicharacter or qb-multicharacter?
No. Character selection and creation are handled by qs-coremulticharacter. The es_extended bridge already answers esx_identity:registerIdentity and esx:playerLogout, so installing the real esx_identity or another multicharacter resource would put two character systems on the same player.
Can I install the real es_extended or qb-core next to it?
No. The bridges already answer as es_extended and qb-core, and two resources cannot share a name. Running the real frameworks would also load a second core for the same players.
Does running two framework bridges slow the server down?
The bridges react to Quasar Framework events instead of polling, and nothing in them runs every frame while players are idle. The only timers are a once-a-second death check on the client for ESX scripts and the LegacyFuel tick, once a second while you drive.
Which ESX and QBCore versions are covered?
The es_extended bridge follows the ESX Legacy API and reports version 1.13.4; the qb-core bridge follows the QBCore API and reports 1.2.0 from GetCoreVersion().
Where do ESX scripts store per-player data?
Wherever they did before — usually their own tables, keyed by xPlayer.identifier. On Quasar Framework that identifier is the character's citizenid, so the data belongs to the character.



