PlayDeck
Home / Guides / QBox Basics: Getting Started with qbx_core and the ox Ecosystem

QBox Basics: Getting Started with qbx_core and the ox Ecosystem

QBox is a modern FiveM roleplay framework built on the foundations of QBCore but rewritten for performance, security, and code quality. Its core resource is qbx_core, and instead of bundling its own inventory and UI, it leans on the widely-used ox ecosystem: ox_lib for shared utilities and UI, ox_inventory for a slot-based inventory, and oxmysql for the database. The result is a leaner, actively-maintained framework that keeps backwards compatibility with a large number of QBCore scripts.

This guide covers the QBox-specific things a beginner needs: how to retrieve a player with the qbx_core export, how QBox favors exports over a core object, where ox_lib fits in, and how QBox differs from QBCore in day-to-day code. If you already know QBCore, this will feel familiar with cleaner edges. PlayDeck teaches QBox the modern way with AI generating qbx_core and ox_lib-correct Lua that you steer and verify, so you learn current best practices instead of legacy patterns.

What makes QBox different

QBox started as a community effort to keep QBCore alive and move it forward. The headline differences are architectural: QBox targets Lua 5.4, uses ox_inventory as the default inventory instead of a bundled one, relies on ox_lib for menus, notifications, and callbacks, and emphasizes state-bag-driven synchronization for things like vehicle keys and player status. It is designed to be lighter and to run smoother on busy servers.

Crucially, QBox maintains backwards compatibility with a large catalog of QBCore resources through a bridge, so server owners can migrate without throwing away their script library. That said, when you write new code for QBox, you should use the native qbx_core exports and ox_lib rather than the legacy QBCore-compatible shims that is the path the documentation recommends and where the performance benefits live.

Getting a player with the qbx_core export

QBox prefers exports over a shared core object. To get a character on the server you call: local player = exports.qbx_core:GetPlayer(source). The returned object exposes player.PlayerData with familiar fields like player.PlayerData.citizenid and player.PlayerData.job. There is no GetCoreObject() requirement the way classic QBCore has you call the export directly wherever you need it.

Money and job functions live on the player object much like QBCore: player.Functions.AddMoney('cash', 1000), player.Functions.RemoveMoney('bank', 500, 'reason'), and player.Functions.SetJob('police', 2). Because items live in ox_inventory, item operations go through ox_inventory exports rather than a built-in inventory for example exports.ox_inventory:AddItem(source, 'water', 1). This split (core for identity and money, ox_inventory for items) is the single biggest mental shift coming from ESX or vanilla QBCore.

ox_lib: callbacks, notifications, and menus

ox_lib is the toolbox QBox builds on, and learning a few of its helpers covers most UI needs without writing raw NUI. lib.notify({ title = 'Done', type = 'success' }) shows a clean notification. lib.callback lets the client request data from the server and await a response in one call, replacing the older pattern of paired client and server events. Context menus and input dialogs come from lib.registerContext and lib.inputDialog.

Using ox_lib means you write far less boilerplate and your scripts look and behave consistently with the rest of the ecosystem. When you do need a fully custom interface, you drop down to NUI covered on the NUI/JS frontend guide but for menus, dialogs, and notifications, reach for ox_lib first.

A minimal QBox command

A complete server-side feature in QBox looks like this: RegisterCommand('givewater', function(source) local player = exports.qbx_core:GetPlayer(source) if not player then return end exports.ox_inventory:AddItem(source, 'water', 1) end). It gives the calling player one water item, handled entirely through the qbx_core and ox_inventory exports.

Notice there is no core object setup line and no manual HUD update the export-first design and ox_inventory handle the plumbing. As always, guard the GetPlayer result for nil and do all authoritative actions on the server. The fundamentals of trusting only the server are identical across ESX, QBCore, and QBox; only the function names change.

Frequently asked questions

Can I run QBCore scripts on QBox?

Many of them, yes. QBox ships a compatibility bridge that maps common QBCore calls to qbx_core, so a large portion of existing QBCore resources run with little or no change. New code, though, should use native qbx_core exports and ox_lib for best performance.

Do I have to use ox_inventory with QBox?

ox_inventory is the default and recommended inventory, and most QBox-native scripts assume it. You can use alternatives through bridges, but you will lose some integration and the smoothest experience comes from staying on ox_inventory.

Is QBox harder to learn than QBCore?

Not really. The core concepts (citizenid, player object, money and job functions) are the same. The main new things are calling exports directly, splitting items out to ox_inventory, and using ox_lib for UI. If you know QBCore, you can pick up QBox in an afternoon.

Why are statebags important in QBox?

State bags let the server attach data to entities or players that automatically syncs to clients without manual event spam. QBox uses them for things like vehicle keys and player status, which is more efficient and less bug-prone than triggering events to everyone.

Build this with AI, no CS degree

PlayDeck teaches you to build and sell GTA roleplay scripts with AI, you steer it and it writes the Lua. GTA 6 is coming. Get on the frontline now.

Join the waitlist