Grand opening25% off everything with FAM-261023-261025-UL4B9this weekendAdded for you at checkout Halloween Edition36 maps, limited runlimited runShop the drop

FREE TOOL · RUNS IN YOUR BROWSER

FiveM inventory icon maker

Drop in your own pictures, or start from a render of one of the game's own objects, and get back square FiveM inventory icons with the background trimmed off — plus the items.lua that goes with them, written for ox_inventory, qb-core and ESX. Every pixel is processed by this tab; no image is sent anywhere.

Drop your PNG or JPG images here

Nothing is uploaded. The trimming, the resizing and the zip all happen in this tab, and the file name becomes the item key.

Or start from a GTA 5 object

Every one of these is a render of the game's own model on a transparent background. Pick one, or type any model name from the object list.

Size
Format
Finish
ox_inventory/data/items.lua

Add an image above and this fills in. Pictures go in ox_inventory/web/images/.

-- ox_inventory/data/items.lua
-- Drop the pictures in ox_inventory/web/images/
-- No client.image line is needed: a .png named after the item key is what
-- ox_inventory looks for by default.
return {
    ['item'] = {
        label = 'Item',
        weight = 500,
        stack = true,
        close = true,
        description = 'Item',
    },
}

HOW TO USE IT

From a loose picture to a working slot

Four steps, and one detail that costs people an evening.

1. Name the files before you drop them

The file name becomes the item key, because that is the only thing an inventory matches on. water_bottle.png gives you an item keyed water_bottle. Lower case, no spaces, underscores instead of dashes — you can still edit the key under each picture afterwards.

2. Trim the background, then check the edges

The trim floods inwards from all four corners and stops where the colour stops matching, so it handles a flat studio background without a mask. Raise the tolerance for a noisy JPEG; lower it if a pale part of the item starts disappearing.

3. Pick one size and keep it

128 px is the safe default for ox_inventory and qb-inventory. What matters more than the number is that every icon in the folder is the same square size — a grid of mixed sizes looks crooked even when each picture is fine.

4. Copy the images into the inventory, not into your resource

They go in ox_inventory/web/images/ or qb-inventory/html/images/ — inside the inventory resource itself, not inside the script that adds the item. Restart the inventory resource afterwards, or the NUI keeps serving the old folder listing.

The ox_inventory .webp trap

ox_inventory looks for the picture in its own web/images folder, named after the item key, and it assumes .png. Ship a .webp and it still asks for name.png, finds nothing, and leaves the slot empty — silently, with no console error, which is why it reads like a broken item rather than a wrong extension. If you export WebP, declare it: client = { image = 'name.webp' }. The tool writes that line for you the moment you switch the format to .webp.

ox_inventory/data/items.lua

Two items: one as a .png, one as a .webp with the line that makes it load.

-- ox_inventory/data/items.lua
return {
    ['water_bottle'] = {
        label = 'Bottle of water',
        weight = 500,
        stack = true,
        close = true,
        description = 'Still cold.',
    },

    -- Same item, shipped as a .webp instead. Without the client.image line
    -- ox_inventory asks for water_bottle.png, gets nothing, and the slot
    -- draws empty with no error anywhere.
    ['energy_drink'] = {
        label = 'Energy drink',
        weight = 350,
        stack = true,
        close = true,
        client = {
            image = 'energy_drink.webp',
        },
    },
}
qb-core/shared/items.lua

qb-inventory reads the image field directly, so a .webp works here as long as the field matches the file name exactly.

-- qb-core/shared/items.lua
['water_bottle'] = {
    ['name'] = 'water_bottle',
    ['label'] = 'Bottle of water',
    ['weight'] = 500,
    ['type'] = 'item',
    ['image'] = 'water_bottle.png',
    ['unique'] = false,
    ['useable'] = true,
    ['shouldClose'] = true,
    ['combinable'] = nil,
    ['description'] = 'Still cold.'
},

QUESTIONS

About FiveM inventory icons

Where do the finished images go?
ox_inventory reads them from ox_inventory/web/images/, qb-inventory from qb-inventory/html/images/, and the older esx_inventoryhud from esx_inventoryhud/html/img/items/. The file name has to match the item key character for character — water_bottle.png for an item keyed water_bottle. A capital letter or a stray space is the single most common reason a slot draws empty, because the inventory asks for a file that is not there and fails silently.
Why does my .webp show nothing in ox_inventory?
Because ox_inventory assumes .png. If the picture is a .webp you have to say so in the item definition: client = { image = 'water_bottle.webp' }. Without that line it requests water_bottle.png, gets a 404 and leaves the slot blank — and nothing is printed in the console, so it reads like a broken item rather than a wrong extension. Either add the line or export as .png.
What size should an inventory icon be?
ox_inventory draws its slots at roughly 100 px on a 1080p screen, so 128 px is the safe default: sharp on a 1440p or 4K client without wasting space. 256 px is worth it only if your NUI scales slots up. 64 px is for a compact hotbar. Whatever you pick, keep every icon the same square size — mixed sizes are what makes a grid look crooked even when each picture is fine on its own.
Does anything get uploaded when I use this?
No. The trimming, the resizing and the zip are all done by your browser with a canvas element. The images never leave the machine, which also means the tool keeps working on a laptop with no connection once the page has loaded.
The background trim ate part of my item. What now?
Lower the tolerance. The trim floods inwards from the four corners and stops where the colour stops matching, so a high tolerance will walk straight through a pale edge — a white mug on a white background is the classic case. Drop the slider until the outline comes back, or turn the trim off entirely for a picture that already has a transparent background.