{"id":153617,"date":"2025-09-05T15:40:58","date_gmt":"2025-09-05T13:40:58","guid":{"rendered":"https:\/\/hifivem.com\/?p=153617"},"modified":"2026-06-22T20:43:52","modified_gmt":"2026-06-22T18:43:52","slug":"pilha-qbox-ox","status":"publish","type":"post","link":"https:\/\/fivemx.com\/pt\/qbox-ox-stack\/","title":{"rendered":"QBOX Framework \u2013 Guia Completo"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Overextended (Ox)<\/strong> is the modern baseline for FiveM servers. This guide shows you how to install, configure, and safely migrate to <strong>ox_inventory<\/strong>, <strong>ox_lib<\/strong>, <strong>ox_target<\/strong>, and <strong><a href=\"https:\/\/fivemx.com\/mysql-async-to-oxmysql\/\" data-type=\"post\" data-id=\"193033\">oxmysql<\/a><\/strong>. You\u2019ll get copy\u2011pasteable code, opinionated defaults, and battle\u2011tested patterns for UI, interactions, and data. Includes playbooks for <strong>qb-inventory \u2192 ox_inventory<\/strong> and <strong>mysql-async \u2192 oxmysql<\/strong>. <strong>Back up your server and database before any change.<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">TL;DR: Which Ox component for what?<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Component<\/th><th>Purpose<\/th><th>Core APIs<\/th><th>Typical Use<\/th><th>Migration Path<\/th><th>Common Gotchas<\/th><\/tr><\/thead><tbody><tr><td><strong>ox_inventory<\/strong><\/td><td>Inventory &amp; items, stashes, shops<\/td><td><code>AddItem<\/code>, <code>RemoveItem<\/code>, <code>RegisterStash<\/code>, <code>RegisterShop<\/code><\/td><td>Player items, job stashes, vendor shops<\/td><td>qb-inventory \u2192 ox_inventory<\/td><td>Wrong item schema, duplicate invs running, missing <code>ensure<\/code> order<\/td><\/tr><tr><td><strong>ox_lib<\/strong><\/td><td>Utilities, UI, helpers<\/td><td><code>addCommand<\/code>, <code>registerContext<\/code>\/<code>showContext<\/code>, <code>inputDialog<\/code>, <code>progressBar<\/code>, <code>zones\/points<\/code><\/td><td>Menus, prompts, rate\u2011limits, zone logic<\/td><td>N\/A<\/td><td>Mixing UI libs, not awaiting callbacks<\/td><\/tr><tr><td><strong>ox_target<\/strong><\/td><td>Interaction targeting<\/td><td><code>addBoxZone<\/code>, <code>addSphereZone<\/code>, <code>addEntity<\/code>, <code>addModel<\/code><\/td><td>Eye targets on props\/peds\/zones<\/td><td>qtarget \u2192 ox_target (optional)<\/td><td>Overlapping zones, missing job conditions<\/td><\/tr><tr><td><strong>oxmysql<\/strong><\/td><td>MySQL driver<\/td><td><code>query<\/code>, <code>single<\/code>, <code>scalar<\/code>, <code>insert<\/code>, <code>prepare<\/code>, <code>transaction<\/code><\/td><td>DB persistence, leaderboards, audits<\/td><td>mysql-async \u2192 oxmysql<\/td><td>Unindexed queries, unsafe string concat<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Tip:<\/strong> Start with <strong>oxmysql<\/strong> and <strong>ox_lib<\/strong>, then migrate <strong>inventory<\/strong> and <strong>target<\/strong>. Validate each step on a staging server.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/frameworks\/\">https:\/\/fivemx.com\/frameworks\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/framework-conversion\/\">https:\/\/fivemx.com\/framework-conversion\/<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/fivemx.com\/qbox-scripts\/\" data-type=\"product_cat\" data-id=\"2907\"><strong>Get QBox Scripts here<\/strong><\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites &amp; Baseline<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Recent server artifact, <strong>txAdmin<\/strong>, and a framework (<strong>QBCore<\/strong> or <strong>ESX<\/strong>).<\/li>\n\n\n\n<li>Node.js is not required for Ox, but your NUI stack (if any) might use it.<\/li>\n\n\n\n<li><strong>Resource start order:<\/strong> <code>oxmysql<\/code> \u2192 <code>ox_lib<\/code> \u2192 <code>ox_inventory<\/code> \u2192 the rest. Put <strong>ox_target<\/strong> early among UI\/interact libs.<\/li>\n\n\n\n<li><strong>Checklist:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Firewall allows DB traffic; DB user has least privileges.<\/li>\n\n\n\n<li>Set production vs dev convars; enable slow query warnings in staging.<\/li>\n\n\n\n<li>Backups for DB and resource configs.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/how-to-install-qbcore\/\">https:\/\/fivemx.com\/how-to-install-qbcore\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/how-to-customize-qbcore-scripts\/\">https:\/\/fivemx.com\/how-to-customize-qbcore-scripts\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/qbcore-scripts\/\">https:\/\/fivemx.com\/qbcore-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Install &amp; Configure: ox_inventory<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Install<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Add the resource and ensure it <strong>after<\/strong> <code>ox_lib<\/code>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- resources\/[ox]\/ox_inventory\/fxmanifest.lua (snippet)\nfx_version 'cerulean'\ngame 'gta5'\n\nlua54 'yes'\nshared_scripts {\n  '@ox_lib\/init.lua',\n  'config.lua'\n}\nclient_scripts { 'client\/*.lua' }\nserver_scripts { '@oxmysql\/lib\/MySQL.lua', 'server\/*.lua' }\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>server.cfg<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">ensure oxmysql\nensure ox_lib\nensure ox_inventory\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Core config<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Define items (weight, stack, metadata). Typical path: <code>ox_inventory\/data\/items.lua<\/code>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">return {\n  water = {\n    label = 'Water Bottle',\n    weight = 200,\n    stack = true,\n    close = true,\n    description = 'Stay hydrated.'\n  },\n  sandwich = { label = 'Sandwich', weight = 300, stack = true }\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Register a <strong>stash<\/strong> and a <strong>shop<\/strong> on server start:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- server\/stash_shop.lua\nCreateThread(function()\n  exports.ox_inventory:RegisterStash('pd_evidence', 'Police Evidence', 100, 100000, false, {police = 2})\n\n  exports.ox_inventory:RegisterShop('corner_store', {\n    name = '24\/7 Market',\n    inventory = {\n      { name = 'water', price = 8 },\n      { name = 'sandwich', price = 12 }\n    }\n  })\nend)\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">UI basics<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Drag &amp; drop, split, stack; configurable hotkeys.<\/li>\n\n\n\n<li>Use <strong>metadata<\/strong> for serials, qualities, expiry.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/chatgpt.com\/g\/g-p-68ba9be056148191b5c3074244ef66ed-fivemx\/c\/68bae2b2-3d78-8331-82df-0a2371ac9ead#placeholder-ox-inventory-shop-stash\" alt=\"ox_inventory \u2014 shop &amp; stash\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Quick test<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Give yourself an item and open inventory:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- server\/debug.lua\nRegisterCommand('giveme', function(src)\n  exports.ox_inventory:AddItem(src, 'water', 1)\nend, true)\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Common mistakes<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Warning:<\/strong> Do <strong>not<\/strong> run two inventories at once. Fully disable qb-inventory before enabling ox_inventory.<\/p>\n<\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Tip:<\/strong> Match item <strong>names<\/strong> exactly across jobs\/crafting and inventory data.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/fivem-inventory-scripts\/\">https:\/\/fivemx.com\/fivem-inventory-scripts\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/qbcore-scripts\/\">https:\/\/fivemx.com\/qbcore-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Install &amp; Configure: ox_lib<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Essentials<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a class=\"wpil_keyword_link\" href=\"https:\/\/fivemx.com\/brand\/core\/\" title=\"Core\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"1784\">Core<\/a> helpers you\u2019ll use everywhere:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- Commands\nlib.addCommand('healme', {\n  help = 'Heal yourself (admin only).',\n  restricted = 'group.admin'\n}, function(src)\n  TriggerClientEvent('fivemx:heal', src)\nend)\n\n-- Context menus\nlib.registerContext({\n  id = 'shop_menu',\n  title = '24\/7 Market',\n  options = {\n    { title = 'Buy Water ($8)', event = 'fivemx:buy', args = { item = 'water', price = 8 } },\n    { title = 'Buy Sandwich ($12)', event = 'fivemx:buy', args = { item = 'sandwich', price = 12 } }\n  }\n})\n-- later\nlib.showContext('shop_menu')\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Mini cookbook<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Input dialog<\/strong> &amp; <strong>progress<\/strong> with awaitable flow:<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- client\nlocal input = lib.inputDialog('Craft Coffee', {\n  { type = 'number', label = 'Beans (g)', default = 18, min = 1, max = 60 }\n})\nif input then\n  local ok = lib.progressBar({ duration = 3500, label = 'Brewing\u2026', useWhileDead = false, canCancel = true })\n  if ok then TriggerServerEvent('fivemx:craft:coffee', input[1]) end\nend\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Callbacks<\/strong> (server validates, client awaits):<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- server\nlib.callback.register('fivemx:buyItem', function(src, item, price)\n  -- validate job\/coords\/etc. then charge + grant\n  -- return true\/false and message\n  return exports.ox_inventory:AddItem(src, item, 1)\nend)\n\n-- client\nlocal success = lib.callback.await('fivemx:buyItem', false, 'water', 8)\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/frameworks\/\">https:\/\/fivemx.com\/frameworks\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/framework-conversion\/\">https:\/\/fivemx.com\/framework-conversion\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Install &amp; Configure: ox_target<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Entities &amp; bones<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Attach actions to specific <strong>peds\/vehicles\/objects<\/strong> or their bones.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- target an entity by model\nexports.ox_target:addModel(`prop_vend_soda_02`, {\n  {\n    name = 'vending_buy',\n    icon = 'fa-solid fa-bottle-water',\n    label = 'Buy a Drink',\n    onSelect = function(data) TriggerEvent('fivemx:openVending') end\n  }\n})\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Zones<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create 3D boxes\/spheres\/polys with job conditions.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- Box zone in front of cash register\nexports.ox_target:addBoxZone({\n  coords = vec3(25.7, -1347.3, 29.5),\n  size = vec3(1.6, 1.2, 1.0),\n  rotation = 0.0,\n  debug = false,\n  options = {\n    {\n      label = 'Open Shop',\n      icon = 'fa-solid fa-store',\n      groups = { police = 0, ambulance = 0 }, -- anyone; example of group filter\n      onSelect = function()\n        lib.showContext('shop_menu')\n      end\n    }\n  }\n})\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Examples<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Stash target<\/strong> for police evidence.<\/li>\n\n\n\n<li><strong>Job\u2011gated crafting<\/strong> inside a workshop.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/chatgpt.com\/g\/g-p-68ba9be056148191b5c3074244ef66ed-fivemx\/c\/68bae2b2-3d78-8331-82df-0a2371ac9ead#placeholder-ox-target-boxzone\" alt=\"ox_target \u2014 addBoxZone example\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/qbcore-scripts\/\">https:\/\/fivemx.com\/qbcore-scripts\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/fivem-inventory-scripts\/\">https:\/\/fivemx.com\/fivem-inventory-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Install &amp; Configure: oxmysql<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Why oxmysql<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prepared statements, pooling, async\/await API.<\/li>\n\n\n\n<li>Better performance and safety than string\u2011concat SQL.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">API cheatsheet<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- read many\nlocal rows = MySQL.query.await('SELECT id, name FROM players WHERE job = ?', { 'police' })\n\n-- read single row\nlocal player = MySQL.single.await('SELECT * FROM players WHERE identifier = ?', { identifier })\n\n-- scalar value\nlocal count = MySQL.scalar.await('SELECT COUNT(*) FROM stash_items WHERE stash = ?', { 'pd_evidence' })\n\n-- insert\nlocal id = MySQL.insert.await('INSERT INTO logs (event, source) VALUES (?, ?)', { 'buy_water', src })\n\n-- prepared &amp; cached\nlocal info = MySQL.prepare.await('SELECT label, weight FROM items WHERE name = ?', { 'water' })\n\n-- transaction\nMySQL.transaction.await(function()\n  MySQL.query.await('UPDATE accounts SET money = money - ? WHERE identifier = ?', { 12, identifier })\n  MySQL.query.await('INSERT INTO purchases (identifier, item) VALUES (?, ?)', { identifier, 'sandwich' })\nend)\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Indexes &amp; schema hygiene<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">ALTER TABLE players ADD INDEX idx_players_identifier (identifier);\nALTER TABLE purchases ADD INDEX idx_purchases_identifier_created (identifier, created_at);\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Error handling<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Tip:<\/strong> Enable slow query warnings in staging and add proper indexes before launch.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/mysql-async-to-oxmysql\/\">https:\/\/fivemx.com\/mysql-async-to-oxmysql\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/sql-identifiers-migration\/\">https:\/\/fivemx.com\/sql-identifiers-migration\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/converting-fivem-scripts\/\">https:\/\/fivemx.com\/converting-fivem-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Migration Playbooks (copy-paste ready)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">qb-inventory \u2192 ox_inventory<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Concepts mapping<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Concept<\/th><th>qb-inventory<\/th><th>ox_inventory<\/th><\/tr><\/thead><tbody><tr><td>Items<\/td><td><code>qb-core\/shared\/items.lua<\/code><\/td><td><code>ox_inventory\/data\/items.lua<\/code><\/td><\/tr><tr><td>Stashes<\/td><td>Job\/player stash logic in scripts<\/td><td><code>RegisterStash(id, label, slots, weight, owner, groups, coords)<\/code><\/td><\/tr><tr><td>Shops<\/td><td>qb-shops or custom<\/td><td><code>RegisterShop(id, { inventory = {..} })<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Steps<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Disable qb-inventory and any inventory\u2011dependent UIs.<\/li>\n\n\n\n<li>Install <strong>ox_lib<\/strong>, <strong>ox_inventory<\/strong>, <strong>oxmysql<\/strong> in that order.<\/li>\n\n\n\n<li>Port items \u2192 <code>data\/items.lua<\/code> (preserve names\/weights\/metadata).<\/li>\n\n\n\n<li>Replace item add\/remove calls with <code>exports.ox_inventory:AddItem\/RemoveItem<\/code>.<\/li>\n\n\n\n<li>Register stashes\/shops server\u2011side; migrate stash save data if applicable.<\/li>\n\n\n\n<li>Test on staging; verify drag\/stack\/split and job stashes.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checklist (Before\/After)<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Area<\/th><th>Before<\/th><th>After<\/th><th>Risk<\/th><\/tr><\/thead><tbody><tr><td>Resources<\/td><td>qb-inventory enabled<\/td><td>qb-inventory removed, ox_inventory ensured<\/td><td>Low<\/td><\/tr><tr><td>Items<\/td><td>items in qb shared<\/td><td>items in <code>data\/items.lua<\/code><\/td><td>Medium (naming)<\/td><\/tr><tr><td>Stashes<\/td><td>implicit<\/td><td>explicit <code>RegisterStash<\/code><\/td><td>Low<\/td><\/tr><tr><td>Shops<\/td><td>qb\u2011shops<\/td><td><code>RegisterShop<\/code><\/td><td>Low<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Example: add\/remove replace<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- before (qb-inventory pseudocode)\n-- QBCore.Functions.AddItem(src, 'water', 1)\n\n-- after (ox_inventory)\nexports.ox_inventory:AddItem(src, 'water', 1)\nexports.ox_inventory:RemoveItem(src, 'sandwich', 1)\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/fivem-inventory-scripts\/\">https:\/\/fivemx.com\/fivem-inventory-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">mysql-async \u2192 oxmysql<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Search\/replace patterns<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>mysql-async call<\/th><th>oxmysql equivalent<\/th><\/tr><\/thead><tbody><tr><td><code>MySQL.Async.fetchAll(sql, params, cb)<\/code><\/td><td><code>MySQL.query(sql, params)<\/code> \/ <code>.await<\/code><\/td><\/tr><tr><td><code>MySQL.Async.fetchScalar(sql, params, cb)<\/code><\/td><td><code>MySQL.scalar(sql, params)<\/code> \/ <code>.await<\/code><\/td><\/tr><tr><td><code>MySQL.Async.execute(sql, params, cb)<\/code><\/td><td><code>MySQL.query(sql, params)<\/code> or <code>MySQL.update\/insert<\/code> \/ <code>.await<\/code><\/td><\/tr><tr><td>string concat <code>\"..var..\"<\/code><\/td><td><code>?<\/code> placeholders with param array<\/td><\/tr><tr><td>manual BEGIN\/COMMIT<\/td><td><code>MySQL.transaction.await(function() ... end)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Example refactor<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- before\nMySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @id', { ['@id'] = identifier }, function(rows)\n  -- use rows\nend)\n\n-- after\nlocal rows = MySQL.query.await('SELECT * FROM users WHERE identifier = ?', { identifier })\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Prepared statements<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">local user = MySQL.prepare.await('SELECT id, job FROM users WHERE identifier = ?', { identifier })\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Warning:<\/strong> Never trust client input. Always validate on the <strong>server<\/strong> and use placeholders.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/mysql-async-to-oxmysql\/\">https:\/\/fivemx.com\/mysql-async-to-oxmysql\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/sql-identifiers-migration\/\">https:\/\/fivemx.com\/sql-identifiers-migration\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/converting-fivem-scripts\/\">https:\/\/fivemx.com\/converting-fivem-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Patterns that sell: building jobs &amp; UI with the Ox stack<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A minimal delivery job that ties <strong>ox_target<\/strong> (interact), <strong>ox_lib<\/strong> (UI), <strong>ox_inventory<\/strong> (rewards), and <strong>oxmysql<\/strong> (audit).<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- client\/jobs_delivery.lua\nlocal drop = vec3(120.4, -1039.2, 29.2)\nexports.ox_target:addBoxZone({\n  coords = drop, size = vec3(1.4, 1.0, 1.0), rotation = 340.0,\n  options = {\n    {\n      name = 'deliver_crate', label = 'Deliver Crate', icon = 'fa-solid fa-box',\n      onSelect = function()\n        local ok = lib.progressBar({ duration = 4000, label = 'Dropping off\u2026' })\n        if ok then TriggerServerEvent('fivemx:job:deliverCrate') end\n      end\n    }\n  }\n})\n<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">-- server\/jobs_delivery.lua\nRegisterNetEvent('fivemx:job:deliverCrate', function()\n  local src = source\n  -- rate limit per minute (very simple)\n  local ok = exports.ox_inventory:AddItem(src, 'water', 1)\n  if ok then\n    MySQL.insert.await('INSERT INTO job_logs (identifier, event) VALUES (?, ?)', { GetPlayerIdentifier(src, 0), 'deliver_crate' })\n    TriggerClientEvent('ox_lib:notify', src, { title = 'Delivery', description = 'You received Water x1', type = 'success' })\n  end\nend)\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/qbcore-scripts\/\">https:\/\/fivemx.com\/qbcore-scripts\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/fivem-inventory-scripts\/\">https:\/\/fivemx.com\/fivem-inventory-scripts\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Performance &amp; Security<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Debounce target interactions; avoid overlapping zones.<\/li>\n\n\n\n<li>Cache frequent reads; <strong>index<\/strong> columns used in WHERE\/JOIN.<\/li>\n\n\n\n<li>Keep server ticks low; move heavy loops off the main thread.<\/li>\n\n\n\n<li>Security: validate server\u2011side, rate\u2011limit economic actions, log sensitive events.<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Tip:<\/strong> Turn on slow\u2011query warnings in staging; ship indexes with migrations.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/converting-fivem-scripts\/\">https:\/\/fivemx.com\/converting-fivem-scripts\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/sql-identifiers-migration\/\">https:\/\/fivemx.com\/sql-identifiers-migration\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Debugging &amp; Test Harness<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add debug <strong>commands<\/strong> guarded by permissions.<\/li>\n\n\n\n<li>Log DB failures and short\u2011circuit on errors.<\/li>\n\n\n\n<li>Test hot\u2011reload by restarting single resources (not the whole stack).<\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">lib.addCommand('oxping', { help = 'Health check', restricted = 'group.admin' }, function(src)\n  local ok = MySQL.scalar.await('SELECT 1') == 1\n  TriggerClientEvent('ox_lib:notify', src, { title = 'Ox Health', description = ok and 'DB OK' or 'DB FAIL', type = ok and 'success' or 'error' })\nend)\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Related:<\/strong> <a href=\"https:\/\/fivemx.com\/frameworks\/\">https:\/\/fivemx.com\/frameworks\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/framework-conversion\/\">https:\/\/fivemx.com\/framework-conversion\/<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Internal Resources &amp; Next Steps<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Frameworks:<\/strong> <a href=\"https:\/\/fivemx.com\/frameworks\/\">https:\/\/fivemx.com\/frameworks\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/framework-conversion\/\">https:\/\/fivemx.com\/framework-conversion\/<\/a><\/li>\n\n\n\n<li><strong>QBCore:<\/strong> <a href=\"https:\/\/fivemx.com\/how-to-install-qbcore\/\">https:\/\/fivemx.com\/how-to-install-qbcore\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/how-to-customize-qbcore-scripts\/\">https:\/\/fivemx.com\/how-to-customize-qbcore-scripts\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/qbcore-scripts\/\">https:\/\/fivemx.com\/qbcore-scripts\/<\/a><\/li>\n\n\n\n<li><strong>Migrations:<\/strong> <a href=\"https:\/\/fivemx.com\/mysql-async-to-oxmysql\/\">https:\/\/fivemx.com\/mysql-async-to-oxmysql\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/sql-identifiers-migration\/\">https:\/\/fivemx.com\/sql-identifiers-migration\/<\/a> \u00b7 <a href=\"https:\/\/fivemx.com\/converting-fivem-scripts\/\">https:\/\/fivemx.com\/converting-fivem-scripts\/<\/a><\/li>\n\n\n\n<li><strong>Inventory hub:<\/strong> <a href=\"https:\/\/fivemx.com\/fivem-inventory-scripts\/\">https:\/\/fivemx.com\/fivem-inventory-scripts\/<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Browse the store<\/strong> for tested scripts that follow these patterns.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Is ox_inventory faster than qb-inventory?<\/strong><br>Generally yes. It emphasizes efficient UI and server\u2011side operations with sane defaults for stacks, weights, and metadata.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can I mix qb-inventory and ox_inventory?<\/strong><br>Not recommended. Stop qb-inventory entirely before enabling ox_inventory to avoid duplicate handlers and item desync.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Do I need to rewrite SQL for oxmysql?<\/strong><br>Mostly search\/replace. Replace string concat with placeholders, adopt <code>*.await<\/code> APIs, and add missing indexes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I secure ox_target interactions?<\/strong><br>Use <code>groups<\/code>\/job checks client\u2011side but always re\u2011validate on the server (distance, job, item ownership) before rewards.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What about ESX compatibility?<\/strong><br>The Ox stack is framework\u2011agnostic. Map ESX events to server handlers and keep inventory names consistent.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I benchmark DB calls?<\/strong><br>Use EXPLAIN, enable slow\u2011query warnings, and compare timings before\/after adding indexes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Where do I define items for ox_inventory?<\/strong><br>In <code>ox_inventory\/data\/items.lua<\/code>. Keep labels short and weights realistic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can I keep qtarget while migrating to ox_target?<\/strong><br>Temporarily, but avoid overlapping zones. Migrate feature\u2011by\u2011feature and remove qtarget when parity is reached.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I migrate stash data?<\/strong><br>Create equivalent <code>RegisterStash<\/code> entries and run SQL to rename old stash IDs to the new keys if needed. Test on staging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I set weights and limits?<\/strong><br>Weights live in <code>items.lua<\/code>. Stash\/shop capacities are part of <code>RegisterStash<\/code>\/<code>RegisterShop<\/code> args.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I rate\u2011limit purchases or jobs?<\/strong><br>Use <code>lib.addCommand<\/code>\/callbacks with simple in\u2011memory cooldowns and server\u2011side validation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Does oxmysql support transactions?<\/strong><br>Yes\u2014wrap atomic sequences in <code>MySQL.transaction.await(function() ... end)<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I handle NUI with Ox?<\/strong><br>Ox plays fine with any NUI; just keep heavy UI logic client\u2011side and validations server\u2011side.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What\u2019s the safest migration order?<\/strong><br>oxmysql \u2192 ox_lib \u2192 ox_inventory \u2192 ox_target. Validate after each step.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Changelog &amp; Credits<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Version<\/th><th>Date<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td>v1.0<\/td><td>2025-09-05<\/td><td>Initial publication with install, config, and migration playbooks.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Last updated:<\/strong> 2025-09-05<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Credits &amp; sources:<\/strong> Overextended documentation (ox_inventory, ox_lib, ox_target), oxmysql reference, Cfx.re docs, and community best practices.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion &amp; Next Steps<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Both frameworks can run a top\u2011tier city. The difference is how much legacy you want to carry and how standardized you want your future to be.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Next steps:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Explore <strong>QBOX Scripts<\/strong> \u2192 <a>https:\/\/fivemx.com\/qbox-scripts\/<\/a><\/li>\n\n\n\n<li>Explore <strong>QBCore Scripts<\/strong> \u2192 <a>https:\/\/fivemx.com\/qbcore-scripts\/<\/a><\/li>\n\n\n\n<li>Read more on <strong>Framework Conversion<\/strong> \u2192 <a>https:\/\/fivemx.com\/framework-conversion<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">External references (learn more)<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>QBOX GitHub (qbx_core)<\/strong> \u2192 <a>https:\/\/github.com\/Qbox-project\/qbx_core<\/a><\/li>\n\n\n\n<li><strong>QBCore GitHub (qb-core)<\/strong> \u2192 <a>https:\/\/github.com\/qbcore-framework\/qb-core<\/a><\/li>\n\n\n\n<li><strong>FiveM Docs \u2014 Resource Manifest (fxmanifest.lua)<\/strong> \u2192 <a>https:\/\/docs.fivem.net\/docs\/scripting-reference\/resource-manifest\/resource-manifest\/<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Overextended (Ox) is the modern baseline for FiveM servers. This guide shows you how to install, configure, and safely migrate to ox_inventory, ox_lib, ox_target, and oxmysql. You\u2019ll get copy\u2011pasteable code, opinionated defaults, and battle\u2011tested patterns for UI, interactions, and data. Includes playbooks for qb-inventory \u2192 ox_inventory and mysql-async \u2192 oxmysql. Back up your server and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":153618,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2877,2347],"tags":[],"class_list":["post-153617","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-free-fivem-job-scripts","category-frameworks"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/posts\/153617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/comments?post=153617"}],"version-history":[{"count":2,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/posts\/153617\/revisions"}],"predecessor-version":[{"id":207140,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/posts\/153617\/revisions\/207140"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/media\/153618"}],"wp:attachment":[{"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/media?parent=153617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/categories?post=153617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemx.com\/pt\/wp-json\/wp\/v2\/tags?post=153617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}