ox_inventory for FiveM
The slot-based inventory most new FiveM servers start with, with first-class support for addon weapons, durability, metadata and shops.
ox_inventory is the inventory the rest of the modern FiveM stack is written against. It is framework agnostic — it runs on ESX, QBCore, Qbox and ox_core — it stores items in slots with per-slot metadata, and it treats weapons as items rather than as a separate system. If you are adding a custom weapon to a server in 2026, this is the file you are most likely editing.
At a glance
| Maintainer | Overextended |
| Latest release | v2.47.9 · 2026-07-13 |
| Last code change | 2026-08-27 |
| Licence | GPL-3.0 |
| Written in | Lua |
| GitHub stars | 564 |
| Status | Active |
Figures read from the repository on 2026-09-22.
Why servers run it
- Weapons are items. A gun in ox_inventory has weight, durability, an ammo type and a serial, and it moves between slots like anything else — no parallel weapon table to keep in sync.
- It is framework independent. The same data/items.lua works whether the server runs ESX Legacy, QBCore, Qbox or ox_core, which is why third-party scripts target it by default.
- Metadata is per slot, not per item name. Two identical pistols can carry different durability, serials and registration — the thing a roleplay server actually needs.
- The UI is a React app served over NUI, so item images are ordinary PNG files you can drop in rather than a spritesheet you have to rebuild.
Installing ox_inventory
1. Install the dependencies first
ox_inventory needs ox_lib and oxmysql. Start them before it in server.cfg — a missing ox_lib is the single most common reason ox_inventory refuses to start.
2. Drop the resource in
Put the ox_inventory folder in your resources directory. Do not rename it: every other script that integrates with it calls exports.ox_inventory by that exact name.
3. Run the SQL
The repository ships a setup SQL file. It creates the inventory tables and, depending on your framework, alters the characters table to hold the inventory column.
4. Point it at your framework
Open fxmanifest.lua and set the framework convar, or set setr inventory:framework in server.cfg. Getting this wrong produces an inventory that loads but never saves.
5. Start it in the right order
ensure oxmysql, then ox_lib, then ox_inventory, then everything that depends on it. Load order is not cosmetic here.
Working examples
data/weapons.lua — registering an addon weapon
-- Every addon weapon needs an entry here before the inventory will accept it.
-- The key is the WEAPON_ name; the hash is derived from it, so it must match
-- the name your weapons.meta declares exactly.
['WEAPON_CUSTOMPISTOL'] = {
label = 'Custom Pistol',
weight = 1000, -- grams
durability = 0.1, -- % lost per shot
ammoname = 'ammo-9', -- shared ammo pool, not per weapon
},
['WEAPON_CUSTOMRIFLE'] = {
label = 'Custom Rifle',
weight = 3300,
durability = 0.03,
ammoname = 'ammo-rifle',
},Giving a weapon from a server script
-- addItem takes the item name, a count and optional metadata. For a weapon
-- the metadata is where the serial, durability and registration live.
exports.ox_inventory:AddItem(source, 'WEAPON_CUSTOMPISTOL', 1, {
serial = 'PTY-' .. math.random(100000, 999999),
durability = 100,
registered = 'John Doe',
})
-- Ammo is a separate item and uses the ammoname from data/weapons.lua
exports.ox_inventory:AddItem(source, 'ammo-9', 60)Checking what a player is carrying
local count = exports.ox_inventory:Search(source, 'count', 'WEAPON_CUSTOMPISTOL')
if count > 0 then
-- They have at least one. Search with 'slots' instead to read the
-- metadata of each individual copy.
local slots = exports.ox_inventory:Search(source, 'slots', 'WEAPON_CUSTOMPISTOL')
print(slots[1].metadata.serial)
endWhat goes wrong
The item image is a file, not a config line. A weapon with no PNG in web/images shows as a blank square. The file name is the lowercased item name plus .png — WEAPON_CUSTOMPISTOL becomes weapon_custompistol.png.
ammoname is an ammo pool, not a weapon. Pointing two weapons at ammo-rifle means they share one magazine count, which is what the base game does too. Inventing a new ammo name also needs a matching item entry.
Durability is a percentage lost per shot, not a hit point total. 0.1 means the weapon is dead after a thousand rounds. Copying a melee value onto a rifle is why some servers have guns that break in a magazine and a half.
Restarting ox_inventory while players are online drops unsaved state. Use a server restart or the refresh export instead; a bare restart ox_inventory is how inventories get wiped on live servers.
The resource folder name is load bearing. Renaming it to something branded breaks every exports.ox_inventory call in every other script you run.
ox_inventory — questions people ask
Does ox_inventory work with ESX and QBCore?
How do I add a custom weapon to ox_inventory?
Why is my weapon image blank?
Where is the ox_inventory documentation?
Runs alongside
The shared library half the modern FiveM ecosystem depends on: menus, notifications, progress bars, zones, callbacks and a cache.
The MySQL wrapper the modern FiveM stack runs on: promise-based, prepared-statement aware and a drop-in replacement for mysql-async.
QBCore's own inventory: the default on every stock QBCore server and still the most widely installed inventory in the ecosystem.
The original FiveM roleplay framework, still running a very large share of live servers — jobs, money, society accounts and a huge script catalogue.
The roleplay framework most new FiveM servers are built on, with the largest modern script ecosystem and a one-click txAdmin recipe.