W-DevelopmentW-Development
Frameworks Updated 10 min read

Making your script work with every common inventory

Integrate FiveM scripts with ox_inventory, qb-inventory and the ESX inventory: item exports, detecting the active one, a small bridge and usable items.

Overview

Almost every script eventually gives, takes or checks items, and every inventory does it differently. A thin inventory layer in your resource — add, remove, count, can carry — keeps the rest of the code identical whether the server runs ox_inventory, qb-inventory or ESX’s default inventory.

The APIs side by side

Operationox_inventoryqb-inventoryESX default
AddAddItem(src, name, n, meta)AddItem(src, name, n, slot, info, reason)xPlayer.addInventoryItem(name, n)
RemoveRemoveItem(src, name, n, meta, slot)RemoveItem(src, name, n, slot, reason)xPlayer.removeInventoryItem(name, n)
CountGetItemCount(src, name)GetItemCount(src, name)xPlayer.getInventoryItem(name).count
Can carryCanCarryItem(src, name, n)CanAddItem(src, name, n)xPlayer.canCarryItem(name, n)
Server-side exports; verified against the current repositories.

A small inventory bridge

server/inventory.lualua
Inv = {}

local kind = GetResourceState('ox_inventory') == 'started' and 'ox'
    or GetResourceState('qb-inventory') == 'started' and 'qb'
    or 'esx'

function Inv.count(src, name)
    if kind == 'ox' then return exports.ox_inventory:GetItemCount(src, name) end
    if kind == 'qb' then return exports['qb-inventory']:GetItemCount(src, name) or 0 end
    local x = ESX.GetPlayerFromId(src)
    local item = x and x.getInventoryItem(name)
    return item and item.count or 0
end

function Inv.remove(src, name, n)
    if kind == 'ox' then return exports.ox_inventory:RemoveItem(src, name, n) end
    if kind == 'qb' then return exports['qb-inventory']:RemoveItem(src, name, n, false, 'script') end
    local x = ESX.GetPlayerFromId(src)
    if not x or x.getInventoryItem(name).count < n then return false end
    x.removeInventoryItem(name, n)
    return true
end

function Inv.add(src, name, n, meta)
    if kind == 'ox' then return exports.ox_inventory:AddItem(src, name, n, meta) end
    if kind == 'qb' then return exports['qb-inventory']:AddItem(src, name, n, false, meta, 'script') end
    local x = ESX.GetPlayerFromId(src)
    if not x then return false end
    x.addInventoryItem(name, n)
    return true
end

Pair it with a framework bridge — see framework bridges. ox_inventory officially supports ox_core, ESX, Qbox and ND_Core; on QBCore, qb-inventory is the default.

Usable items

InventoryHow
ox_inventoryclient.export/server.export on the item in items.lua — see ox_inventory items
QBCore / qb-inventoryQBCore.Functions.CreateUseableItem(name, fn)
ESXESX.RegisterUsableItem(name, fn)

Rules that prevent dupes

  • Remove the cost first and reward only if the removal returned success.
  • Check carry capacity before adding, or handle the failure.
  • All item operations happen on the server — see secure server events.
  • Use inventory hooks for global rules — see ox_inventory hooks.

Frequently asked questions

How do I add an item with ox_inventory from my script?

On the server: exports.ox_inventory:AddItem(source, 'itemname', count, metadata).

How do I support ox_inventory and qb-inventory at once?

Detect which is started with GetResourceState and route add/remove/count through a small bridge module.

How do I count items in ESX without ox_inventory?

xPlayer.getInventoryItem('name').count.

How do I prevent item duplication?

Do everything on the server and only reward after a successful removal.

Need this built, not just explained?

Premium ESX, QBCore & Qbox scripts with instant delivery — or a custom resource, React NUI and the web stack around your server, built to spec.

Related guides