Framework hub
Move into the QBCore landing page to compare verified scripts, framework fit, and install-ready products built for modern FiveM servers.
Open QBCore hubUse this guide to narrow the framework decision, then move into the core commercial hubs for verified scripts, curated bundles, and a faster server launch path.
Framework hub
Move into the QBCore landing page to compare verified scripts, framework fit, and install-ready products built for modern FiveM servers.
Open QBCore hubFramework hub
Use the ESX landing page to compare framework-specific resources, launch guidance, and premium products that fit ESX-first servers.
Open ESX hubPremium catalog
Move from research into the main shop to compare real products, framework labels, screenshots, and production-ready quality signals.
Open premium shopEasily boost your FiveM server with qbCore, the open‑source framework that simplifies setup, updates, and customization. Follow our friendly step‑by‑step guide and bring immersive role‑play to your co
Choosing a framework is the single most consequential decision when building a FiveM server. It determines which scripts you can use, how your developers write code, the…
FiveM frameworks form the backbone of roleplay servers. They're not just code libraries—they're complete systems that manage player identity, jobs, inventory, permissions,…
QBox has firmly established itself as the natural successor to QBCore in the FiveM roleplay ecosystem.

QBox has firmly established itself as the natural successor to QBCore in the FiveM roleplay ecosystem. If you are running a QBCore server in 2026 and wondering whether to make the switch, or if you are starting fresh and choosing between frameworks, this guide covers everything you need to know: real performance numbers, a step-by-step migration process, code-level conversion examples, and the pitfalls that trip up most server owners during the transition.

QBox (sometimes written as Qbox or qbx) is a FiveM roleplay framework built by former QBCore contributors who wanted to address the performance, security, and code quality issues that had accumulated in the original project. Rather than patching QBCore endlessly, they forked it and rebuilt the architecture around the Overextended (ox) ecosystem.
The result is a modular framework where qbx_core serves as the foundation, but heavy lifting is delegated to purpose-built libraries: ox_lib for utilities and UI, ox_inventory for item management, oxmysql for database operations, and ox_target for interaction targeting. This is not a monolithic framework. Each component can be updated independently without breaking the rest of your server.
QBox ships with several features built directly into qbx_core that previously required separate resources on QBCore: multicharacter selection, a server queue system, multijob and multigang support, and Discord Rich Presence. All of these are enabled by default and configurable through simple Lua config files.
Performance claims without numbers are worthless, so let us look at actual benchmark data from the FiveM community in 2025-2026. These numbers come from controlled tests running identical server configurations with 64 players.
| Framework | Core Resource CPU | Total Framework Overhead | Relative Performance |
|---|---|---|---|
| ESX Legacy | 0.01-0.02ms | ~0.30ms | Baseline (fastest) |
| QBox | 0.00-0.01ms | ~0.42ms | ~25% more than ESX |
| QBCore | 0.02-0.05ms | ~0.73ms | ~43% more than ESX |
| Framework | Core Memory | With Inventory | Total Stack |
|---|---|---|---|
| ESX Legacy | ~18 MiB | ~25 MiB (qs-inventory) | ~45 MiB |
| QBox | ~22 MiB | ~30 MiB (ox_inventory) | ~55 MiB |
| QBCore | ~28 MiB | ~40 MiB (qb-inventory) | ~75 MiB |
ESX Legacy remains the raw performance champion. That has not changed in 2026. However, QBox closes the gap significantly compared to QBCore, using roughly 25-40% less CPU depending on the server load and script count. For most servers, the difference between ESX and QBox is imperceptible to players. The difference between QBCore and QBox, on the other hand, translates directly into better tick rates and smoother gameplay, especially on servers running 80+ resources.
QBox achieves these gains through several architectural decisions: lazy loading of modules, elimination of redundant polling loops that existed in QBCore, native use of ox_lib's optimized utility functions, and a cleaner event system that reduces unnecessary network traffic.
Before touching a single file on your production server, work through this checklist. Skipping any of these steps is the primary reason migrations fail.
mysqldump --all-databases > backup_$(date +%Y%m%d).sqlrefresh in the txAdmin console and export your resource list. Note which scripts are QBCore-native and which are third-partyplayer.citizenid column must use utf8mb4_unicode_ci collation. Check and change it if neededThe cleanest migration path uses the official txAdmin recipe. This downloads and configures all required files automatically: server.cfg, ox.cfg, permissions.cfg, and voice.cfg.
If you cannot use the recipe (for example, on a custom hosting setup), manually download qbx_core from the QBox GitHub repository and follow the configuration files in the txAdminRecipe repository.
Install the ox dependencies in this exact order, validating that each one starts without errors before moving to the next:
Your server.cfg resource start order should reflect this dependency chain:
ensure oxmysql
ensure ox_lib
ensure ox_inventory
ensure qbx_core
ensure ox_target
# ... your other resources below
Add this convar to your server.cfg before the resource ensures:
setr inventory:framework "qbx"
Then run the ox_inventory database conversion script. This migrates your existing item data from qb-inventory's format to ox_inventory's format. Back up your database before this step. The conversion is documented in the ox_inventory documentation.
This is the single most common source of errors during migration. In QBCore, job grades are stored as strings. In QBox, they are numbers.
QBCore format (jobs.lua):
['police'] = {
label = 'Law Enforcement',
grades = {
['0'] = { name = 'Recruit', payment = 500 },
['1'] = { name = 'Officer', payment = 750 },
['2'] = { name = 'Sergeant', payment = 1000 },
['3'] = { name = 'Lieutenant', payment = 1250 },
['4'] = { name = 'Chief', payment = 1500, isboss = true },
},
},
QBox format (jobs.lua):
['police'] = {
label = 'Law Enforcement',
grades = {
[0] = { name = 'Recruit', payment = 500 },
[1] = { name = 'Officer', payment = 750 },
[2] = { name = 'Sergeant', payment = 1000 },
[3] = { name = 'Lieutenant', payment = 1250 },
[4] = { name = 'Chief', payment = 1500, isboss = true },
},
},
The change is subtle but critical: ['0'] becomes [0], ['1'] becomes [1], and so on. Apply this to both qbx_core/shared/jobs.lua and qbx_core/shared/gangs.lua.
Execute the qbx_core.sql file included with qbx_core. This creates the additional database tables QBox needs, including tables for the multijob and multigang systems. If your player.citizenid column does not have utf8mb4_unicode_ci collation, fix that first or the SQL will fail.
QBox bundles features that were separate resources on QBCore. Decide which ones you want:
-- qbx_core/config/client.lua
Config = {
useExternalCharacters = false, -- set true if using a separate multichar resource
-- Discord Rich Presence settings at bottom of file
}
-- server.cfg
setr qbx:enablequeue true # built-in queue system
setr qbx:max_jobs_per_player 1 # multijob limit (cannot be disabled)
setr qbx:max_gangs_per_player 1 # multigang limit (cannot be disabled)
Start your development server and systematically test each resource. Focus on:
While QBox maintains approximately 99% backwards compatibility with , converting your resources to use native QBox APIs improves performance and future-proofs your code. The core object (QBCore = exports['qb-core']:GetCoreObject()) no longer exists in QBox. Instead, you use exports and imported modules.
First, add the QBox module imports to your script's manifest:
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
shared_scripts {
'@ox_lib/init.lua',
'@qbx_core/modules/lib.lua',
}
client_scripts {
'@qbx_core/modules/playerdata.lua',
'client/main.lua',
}
server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/main.lua',
}
Here is a practical before-and-after for a typical client script:
Before (QBCore):
local QBCore = exports['qb-core']:GetCoreObject()
RegisterNetEvent('myresource:client:doSomething', function()
local PlayerData = QBCore.Functions.GetPlayerData()
local job = PlayerData.job.name
local plate = QBCore.Functions.GetPlate(GetVehiclePedIsIn(PlayerPedId(), false))
if job == 'police' then
exports['qb-core']:DrawText('You are on duty', 'left')
Wait(3000)
exports['qb-core']:HideText()
end
end)
After (QBox):
RegisterNetEvent('myresource:client:doSomething', function()
local job = QBX.PlayerData.job.name
local plate = qbx.getVehiclePlate(GetVehiclePedIsIn(PlayerPedId(), false))
if job == 'police' then
lib.showTextUI('You are on duty', { position = 'left-center' })
Wait(3000)
lib.hideTextUI()
end
end)
Notice: no core object initialization, no exports call to get the core. QBX.PlayerData is available directly through the imported playerdata module, and qbx.getVehiclePlate() comes from the lib module.
This is where most script conversions break. QBCore callbacks do not fire on QBox if you use the old registration pattern:
Before (QBCore):
-- Server
QBCore.Functions.CreateCallback('myresource:server:getData', function(source, cb)
local result = MySQL.query.await('SELECT * FROM my_table')
cb(result)
end)
-- Client
QBCore.Functions.TriggerCallback('myresource:server:getData', function(result)
print(json.encode(result))
end)
After (QBox / ox_lib):
-- Server
lib.callback.register('myresource:server:getData', function(source)
return MySQL.query.await('SELECT * FROM my_table')
end)
-- Client
local result = lib.callback.await('myresource:server:getData')
print(json.encode(result))
The ox_lib callback system is cleaner and eliminates the callback pyramid pattern. It uses await instead of nested callbacks, making your code significantly more readable.
| QBCore | QBox Equivalent |
|---|---|
QBCore.Functions.GetPlayerData() | QBX.PlayerData |
QBCore.Functions.GetPlate(vehicle) | qbx.getVehiclePlate(vehicle) |
QBCore.Shared.Jobs | exports.qbx_core:GetJobs() |
QBCore.Shared.Gangs | exports.qbx_core:GetGangs() |
QBCore.Shared.Vehicles | exports.qbx_core:GetVehiclesByName() |
QBCore.Shared.Weapons | exports.qbx_core:GetWeapons() |
QBCore.Shared.Items | exports.ox_inventory:Items() |
exports['qb-core']:DrawText() | lib.showTextUI() |
exports['qb-core']:HideText() | lib.hideTextUI() |
QBCore.Functions.CreateCallback | lib.callback.register |
QBCore.Functions.TriggerCallback | lib.callback.await |
Here is the current compatibility status of popular scripts with QBox as of March 2026:
| Script Category | Popular Scripts | QBox Status | Notes |
|---|---|---|---|
| Inventory | ox_inventory | Native | Default with QBox |
| Phone | qb-phone / lb-phone | Compatible | Works via bridge layer |
| Housing | qb-houses / bcs-housing | Compatible | Minor config changes |
| Vehicles | qb-vehicleshop | Compatible | Works without changes |
| Garages | qb-garages / jg-advancedgarages | Compatible | Works without changes |
| Banking | qb-banking / Renewed-Banking | Needs Update | Must adapt to ox_inventory money |
| Police | qb-policejob | Compatible | QBox has native replacement (qbx_policejob) |
| EMS | qb-ambulancejob | Compatible | QBox has native replacement (qbx_ambulancejob) |
| Mechanic | qb-mechanicjob | Compatible | Works via bridge layer |
| Crafting | qb-crafting | Needs Update | Must use ox_inventory crafting API |
| Target | ox_target | Native | Replaces qb-target |
| UI/TextUI | ox_lib | Native | Replaces qb-core DrawText |
| Multicharacter | Built into qbx_core | Native | No separate resource needed |
| Loading Screen | Custom | Compatible | Framework-independent |
| HUD | qb-hud / ps-hud | Compatible | Works without changes |
| Doorlock | ox_doorlock | Native | Replaces qb-doorlock |
This is the number one migration error. If your scripts or database still reference job grades as strings ('0', '1'), things will break silently. Grade-based permission checks will fail, boss menus will not load, and job actions will be denied without clear error messages.
Fix: Search your entire resources folder for grade comparisons and ensure they use numbers. Check your database records too.
If you migrate to QBox but keep scripts using QBCore.Functions.CreateCallback, those callbacks will hang indefinitely on the client side. The QBCore bridge does not fully replicate the old callback system.
Fix: Convert all callbacks to lib.callback.register and lib.callback.await from ox_lib.
ox_inventory uses a different item registration system than qb-inventory. Items defined in qb-core/shared/items.lua need to be registered in ox_inventory's items configuration instead.
Fix: Run the ox_inventory conversion tool and verify all item names match across your scripts.
Running mysql-async alongside oxmysql causes connection pool conflicts and race conditions.
Fix: Remove mysql-async entirely. Replace all mysql-async calls with oxmysql's await API pattern.
ox_lib must start before qbx_core. ox_inventory must start before most gameplay resources. Getting this wrong causes cascading nil reference errors.
Fix: Follow the exact resource start order outlined in Step 2 of the migration section above.
The honest answer depends on your situation:
Migrate now if:
Wait or skip if:
For new servers in 2026, QBox is the clear recommendation. It offers better performance than QBCore, a modern developer experience through the ox ecosystem, and active maintenance from a dedicated team. The backwards compatibility layer means you are not locked out of the massive QBCore script ecosystem, and the migration path is well-documented.
If you want to explore the framework comparison in more depth, check out our QBox vs QBCore comparison or dive into the complete QBox and Ox stack guide for the full picture of how the Overextended ecosystem fits together.
For servers looking to stock up on compatible scripts, browse our -- we test all scripts for QBox compatibility and label them accordingly.
Yes, QBox maintains backwards compatibility with most QBCore resources through its compatibility layer. However, some scripts that deeply hook into QBCore internals may need minor adjustments.
Based on community benchmarks, QBox with ox_lib typically uses 25-40% less CPU than a comparable QBCore setup. ESX Legacy still edges out both in raw performance, but QBox offers better developer experience and modern tooling.
If your server is stable and players are happy, there's no urgent need. But for new servers or planned overhauls, QBox is the recommended choice in 2026 due to better performance, ox_inventory by default, and active development.
For a typical QBCore server with 30-50 scripts, expect 2-4 days for the core migration and testing. Most QBCore scripts work without changes, but inventory and banking scripts may need updates for ox_inventory compatibility.
Launch faster
Bundles shorten the path from planning to launch by grouping the highest-leverage scripts into a cleaner commercial starting point.