# Using ox_inventory (/docs/guides/ox-inventory)

ESX Legacy works with [ox_inventory](https://github.com/overextended/ox_inventory) out of the box. Start ox_inventory after `es_extended`, and es_extended detects it, switches to its built-in ox bridge and forwards the usual `xPlayer` inventory and cash functions to ox_inventory. You do not edit `Config.CustomInventory`. Items, weapons and stashes are then managed by ox_inventory, not by ESX.

## Overview [#overview]

- Bridge files: `es_extended/server/bridge/inventory/oxinventory.lua` and `es_extended/server/classes/overrides/oxinventory.lua`
- Detection: `shared/config/main.lua`, below the "DO NOT CHANGE" line
- Requires: `oxmysql`, `ox_lib` (required by ox_inventory itself), `esx_lib`, `es_extended`
- Official ox_inventory docs: [overextended.dev/ox_inventory](https://overextended.dev/ox_inventory)

## How ESX detects ox_inventory [#how-esx-detects-ox_inventory]

The detection is one block at the bottom of the main config:

```lua title="es_extended/shared/config/main.lua"
if GetResourceState("ox_inventory") ~= "missing" then
    Config.CustomInventory = "ox"
end

Config.EnableDefaultInventory = Config.CustomInventory == false -- Display the default Inventory ( F2 )
```

So ESX switches to ox mode whenever the `ox_inventory` folder **exists** in your resources, even if you never `ensure` it. In ox mode, `es_extended` also:

- sets `Config.OxInventory = true` (a backwards-compatibility flag that older scripts still read)
- sets the replicated convars `inventory:framework` to `esx` and `inventory:weight` to `Config.MaxWeight * 1000`
- skips `ESX.RefreshItems()` at startup and loads the item list from ox_inventory instead
- does not register the ESX inventory commands (`/giveitem`, `/giveweapon`, `/giveammo`, `/giveweaponcomponent`, `/refreshitems`, `/clearinventory`, `/clearloadout`)
- disables the default F2 inventory

<Callout type="warn" title="Remove the folder if you do not use it">
If you downloaded ox_inventory but decided not to use it, delete or rename the folder. A folder that exists but is not started still puts ESX into ox mode, and players will have no working inventory.
</Callout>

## Set up ox_inventory with ESX [#set-up-ox_inventory-with-esx]

<Steps>
<Step>
### Install the dependencies [#install-the-dependencies]

Download the latest releases of `ox_lib` and `ox_inventory` from Overextended (use the release zip, not the source code, because the UI needs to be built). Put them in your resources folder. `oxmysql`, `esx_lib` and `es_extended` are already part of an ESX install.
</Step>
<Step>
### Set the start order [#set-the-start-order]

ox_inventory loads its ESX bridge when it starts, so `es_extended` must already be running.

```bash title="server.cfg"
ensure oxmysql
ensure ox_lib
ensure esx_lib
ensure es_extended
ensure ox_inventory
ensure [core]
ensure [esx_addons]
```

If you use `ensure [core]` for all core resources, keep `es_extended` above it as in the txAdmin recipe and place `ox_inventory` right after `es_extended`.
</Step>
<Step>
### Set the convars [#set-the-convars]

ESX already replicates `inventory:framework` and `inventory:weight`. Set the rest yourself, for example which ESX accounts are handled as items:

```bash title="server.cfg"
setr inventory:framework "esx"
setr inventory:accounts '["money", "black_money"]'
```

Accounts listed in `inventory:accounts` live inside the ox_inventory as items. `bank` normally stays an ESX account. The ESX bridge always treats `black_money` as an inventory account, even if you leave it out of the convar. See the ox_inventory docs for all other convars (slots, drop distance, police jobs and so on).
</Step>
<Step>
### Define your items [#define-your-items]

Add items to `ox_inventory/data/items.lua`. The ESX `items` table is not used in ox mode.

```lua title="ox_inventory/data/items.lua"
['coffee'] = {
    label = 'Coffee',
    weight = 200,
    stack = true,
    close = true,
},
```

Weights in ox_inventory are in grams. That is why ESX multiplies `Config.MaxWeight` (24 by default) by 1000 when it sets `inventory:weight`.
</Step>
<Step>
### Restart and check [#restart-and-check]

Restart the whole server (not only one resource). In the server console you should see es_extended initialize without errors and ox_inventory report that it loaded the ESX framework. Join and open the ox inventory with its default key.
</Step>
</Steps>

## What changes for your scripts [#what-changes-for-your-scripts]

The xPlayer API stays the same for the common calls. The ox override routes them to ox_inventory exports:

| xPlayer method | In ox mode |
| --- | --- |
| `getInventoryItem(name, metadata)` | `ox_inventory` `GetItem` |
| `addInventoryItem(name, count, metadata, slot)` | `AddItem` |
| `removeInventoryItem(name, count, metadata, slot)` | `RemoveItem` |
| `setInventoryItem(name, count, metadata)` | `SetItem` |
| `canCarryItem(name, count, metadata)` | `CanCarryItem` |
| `canSwapItem(...)` | `CanSwapItem` |
| `setMaxWeight(weight)` | `SetMaxWeight` |
| `hasItem(name, metadata)` | returns `item, count` or `false` |
| `getInventory(minimal)` | ox slots; minimal returns `{ name, count, slot, metadata }` entries |
| `getLoadout()` | always `{}` |
| `addWeapon`, `removeWeapon`, `addWeaponAmmo` and other weapon methods | do nothing |
| `hasWeapon`, `hasWeaponComponent` | always `false` |
| `addAccountMoney` / `removeAccountMoney` / `setAccountMoney` | item change for accounts in `inventory:accounts`, normal ESX account otherwise |

Note the extra `metadata` and `slot` parameters, which exist only in ox mode. Code written for the default ESX inventory keeps working because the extra parameters are optional.

```lua title="server/main.lua"
local xPlayer = ESX.GetPlayerFromId(source)

if xPlayer.canCarryItem('coffee', 1) then
    xPlayer.addInventoryItem('coffee', 1)
end

-- Works in both modes: hasItem returns false when the player has none
if xPlayer.hasItem('lockpick') then
    -- ...
end
```

### Money with ox_inventory [#money-with-ox_inventory]

With the default `inventory:accounts`, cash (`money`) and `black_money` are inventory items. `xPlayer.addMoney`, `removeMoney` and `getAccount('money')` still work because ESX syncs the item count back into the player's accounts. Unlike the default ESX mode, the ox versions of the account methods return `false` instead of throwing an error for an invalid account name or amount. Check the return value. See [Money and accounts](/docs/guides/money-and-accounts).

### Usable items [#usable-items]

`ESX.RegisterUsableItem` still stores the handler in ox mode. How an item is used, and whether it is removed, is decided by ox_inventory's item definition (`consume`, `client`, `server.export`). Check the ox_inventory item docs when you port usable items, and test each one. For new scripts, defining the use behavior in `data/items.lua` with a `server.export` is the most direct option:

```lua title="ox_inventory/data/items.lua"
['coffee'] = {
    label = 'Coffee',
    weight = 200,
    server = {
        export = 'mycafe.useCoffee',
    },
},
```

### Weapons [#weapons]

Weapons are items in ox_inventory. Scripts that give weapons with `xPlayer.addWeapon` silently do nothing in ox mode. Replace those calls with `xPlayer.addInventoryItem('WEAPON_PISTOL', 1)` or the ox_inventory exports.

## Moving from the ESX inventory to ox_inventory [#moving-from-the-esx-inventory-to-ox_inventory]

<Steps>
<Step>
### Back up the database [#back-up-the-database]

Inventory and loadout data are stored as JSON in `users.inventory` and `users.loadout`. Take a full dump before you switch.
</Step>
<Step>
### Port the item list [#port-the-item-list]

Every item in the ESX `items` table that players can own needs an entry in `ox_inventory/data/items.lua`, with the same name. Items that are missing in ox_inventory are dropped from inventories.
</Step>
<Step>
### Convert player data [#convert-player-data]

ox_inventory ships a conversion path for ESX data. Follow the current instructions in the ox_inventory documentation, because the details change between ox releases. Run it once on a test copy of your database first.
</Step>
<Step>
### Update scripts that use ESX inventory internals [#update-scripts-that-use-esx-inventory-internals]

Search your resources for `addWeapon`, `getLoadout`, `esx:useItem`, `esx:addInventoryItem` and `ESX.ShowInventory`. Those rely on the default ESX inventory and need ox equivalents.
</Step>
</Steps>

## Common issues [#common-issues]

- **No inventory at all**: the `ox_inventory` folder exists but is not started, so ESX is in ox mode without an inventory. Start ox_inventory or remove the folder.
- **ox_inventory errors about the framework on start**: it started before `es_extended`. Fix the order in `server.cfg`.
- **`/giveitem` does nothing or is unknown**: in ox mode ESX does not register its inventory commands. Use the ox_inventory admin commands instead.
- **Cash shows 0 after switching**: `money` is now an item. Old balances stay in `users.accounts` until a conversion moves them. Starting money for new players is given as an item from `Config.StartingAccountMoney` for accounts that are in `inventory:accounts`.
- **Weapon shop or job armory gives nothing**: the script uses `xPlayer.addWeapon`. Change it to items.
- **Scripts checking `Config.OxInventory`**: still works, ESX sets it from `Config.CustomInventory == "ox"`. New code can check `ESX.GetConfig('CustomInventory') == 'ox'` on the client.

## Related [#related]

- [esx_inventory (default inventory)](/docs/core/esx_inventory)
- [Add items](/docs/guides/add-items)
- [Money and accounts](/docs/guides/money-and-accounts)
- [Main config](/docs/es_extended/config)
- [xPlayer reference](/docs/es_extended/server/xplayer)
