qb-inventory for FiveM
QBCore's own inventory: the default on every stock QBCore server and still the most widely installed inventory in the ecosystem.
qb-inventory ships with QBCore and is what a server runs until somebody decides to change it. It is tightly coupled to the framework — items live in qb-core/shared/items.lua, weapons in qb-core/shared/weapons.lua — which makes it simpler to reason about than a bridged inventory and harder to move away from later.
Why servers run it
- It is already there. A stock QBCore install has a working inventory, shops, stashes and glove boxes with no extra steps.
- The item table is one file. shared/items.lua is a flat Lua table, which is the easiest possible thing to script against or to generate.
- Weapons are registered in shared/weapons.lua keyed by weapon hash, so a custom gun is two table entries and an image.
- Every QBCore tutorial written since 2021 assumes it, which matters more than it should when you are debugging at 2am.
Installing qb-inventory
1. It is already installed
A stock QBCore server from the txAdmin recipe has qb-inventory running. If you removed it, drop it back into [qb] and ensure it after qb-core.
2. Add your items
Items go in qb-core/shared/items.lua. Each one needs a name, label, weight, type, image file name and a description.
3. Add your weapons
Weapons go in qb-core/shared/weapons.lua, keyed by the weapon hash in backticks. The backticks matter — quotes produce a string key the framework will never match.
4. Drop the images in
Item images live in qb-inventory/html/images. The file name must match the item's image field exactly.
5. Restart the framework
qb-core has to restart for a new shared table to be read, not just the inventory.
Working examples
qb-core/shared/weapons.lua — the backtick trap
-- CORRECT: backticks compile the name to its hash at load time
[`weapon_custompistol`] = {
['name'] = 'weapon_custompistol',
['label'] = 'Custom Pistol',
['weapontype'] = 'Pistol',
['ammotype'] = 'AMMO_PISTOL',
['damagereason'] = 'Shot / Pistol-whipped',
},
-- WRONG: a plain string key. This compiles, loads, and silently never matches.
['weapon_custompistol'] = { ... }qb-core/shared/items.lua — the matching item
['weapon_custompistol'] = {
['name'] = 'weapon_custompistol',
['label'] = 'Custom Pistol',
['weight'] = 1000,
['type'] = 'weapon',
['ammotype'] = 'AMMO_PISTOL',
['image'] = 'weapon_custompistol.png',
['unique'] = true,
['useable'] = false,
['description'] = 'A custom sidearm.',
},Giving the weapon from a server script
local Player = QBCore.Functions.GetPlayer(source)
Player.Functions.AddItem('weapon_custompistol', 1, false, {
serie = tostring(math.random(100000, 999999)),
quality = 100,
})
TriggerClientEvent('inventory:client:ItemBox', source,
QBCore.Shared.Items['weapon_custompistol'], 'add')What goes wrong
Backticks, not quotes, in shared/weapons.lua. [\weapon_x\] evaluates to a hash; ['weapon_x'] is a string key nothing looks up. This is the single most common QBCore weapon bug.
Item names are lowercase. QBCore lowercases item names internally; a mixed-case name in items.lua will not resolve.
unique = true for weapons. Without it the inventory stacks two pistols into one slot and the serial numbers collapse into one.
qb-core must restart, not qb-inventory. The shared tables are read by the core, so restarting only the inventory leaves the old item list in memory.
Image file names include the extension in the config. items.lua wants weapon_custompistol.png, not weapon_custompistol.
qb-inventory — questions people ask
Is qb-inventory better than ox_inventory?
Where do qb-inventory item images go?
Why does my QBCore weapon do nothing?
Runs alongside
The roleplay framework most new FiveM servers are built on, with the largest modern script ecosystem and a one-click txAdmin recipe.
The slot-based inventory most new FiveM servers start with, with first-class support for addon weapons, durability, metadata and shops.
QBCore's third-eye targeting system, and the export signature a very large number of existing scripts are written against.