Skip to content

Installing Lumo UI ​

This guide covers QBCore, Qbox, ESX Legacy and standalone servers: what to install, what to remove, which files to change, and how to fix the resources that are affected. Read the part for your framework, then the troubleshooting table.


What is in the download ​

[lumo-ui]/
├── lumo-ui/            the product: HUD, notifications, target eye, radial,
│                       context menu, input dialog, progress bar, text UI
├── lumo-interact/      walk-up "press E / hold G" prompts (drawn by lumo-ui)
├── lumo-chat-theme/    the Lumo look for FiveM's chat, plus /me
└── [compat]/           drop-in shims, each one its own resource
    ├── qb-target/        exports['qb-target']:* and exports.qtarget:*
    ├── qb-menu/          exports['qb-menu']:openMenu, qb-menu:client:openMenu
    ├── qb-input/         exports['qb-input']:ShowInput
    ├── qb-radialmenu/    exports['qb-radialmenu']:AddOption / RemoveOption
    ├── progressbar/      exports['progressbar']:Progress*, QBCore.Functions.Progressbar
    ├── esx_notify/       ESX.ShowNotification          (ESX only)
    ├── esx_progressbar/  ESX.Progressbar               (ESX only)
    ├── esx_textui/       ESX.TextUI / ESX.HideUI       (ESX only)
    └── lumo-hud-ui/      exports['lumo-hud-ui']:*      (older Lumo scripts)

A shim has the same name as the resource it replaces and forwards its exports and events to lumo-ui. Your other scripts keep calling exports['qb-target']:AddBoxZone(...) and never notice the change.

Two rules for shims:

  1. A shim and the original cannot both be in resources/. FiveM loads only one of two resources with the same name, and you cannot choose which. For every shim you use, move the original folder out of resources/ (not just its ensure line).
  2. Delete the shims you do not use from [compat], for the same reason. For example, on QBCore delete esx_notify, esx_progressbar and esx_textui; on ESX keep qb-target only if you use Lumo's target eye.

Do not ensure [lumo-ui] as a whole folder: ensure each resource by name, as shown below, so only the shims you chose start.


Before you start ​

  1. Back up resources/ and server.cfg.

  2. Requirements: oxmysql. Nothing else.

  3. Make a folder nothing ensures, for example resources/[disabled]/. The old resources go there, so you can put them back later.

  4. Put the [lumo-ui] folder in resources/.

  5. Give your admins the /ui admin tab, in server.cfg:

    cfg
    add_ace group.admin lumo.ui.admin allow

    On QBCore and Qbox the god and admin permissions also count, and on ESX the admin group (LumoUiConfig.AdminPermissions in config.lua).


QBCore ​

Lumo UI replaces the whole qb-* interface layer.

1. Move these folders to [disabled] ​

Old resourceReplaced byShim to ensure
qb-hudlumo-ui HUD—
qb-target (or qtarget)lumo-ui target eyeqb-target
qb-menulumo-ui context menuqb-menu
qb-inputlumo-ui input dialogqb-input
qb-radialmenulumo-ui radialqb-radialmenu
progressbarlumo-ui progress barprogressbar

Also move any other HUD (ps-hud, jg-hud, …): two HUDs draw on top of each other. Keep PolyZone if other scripts use it; lumo-ui does not need it.

2. server.cfg ​

Right after qb-core (and before your jobs and other scripts):

cfg
ensure oxmysql
ensure qb-core
ensure lumo-ui
ensure lumo-interact
ensure lumo-chat-theme   # after chat
ensure qb-target
ensure qb-menu
ensure qb-input
ensure qb-radialmenu
ensure progressbar

3. Notifications (one edit in qb-core) ​

QBCore.Functions.Notify draws qb-core's own notification. To have lumo-ui draw it, open qb-core/client/functions.lua, find function QBCore.Functions.Notify(text, texttype, length, icon) and add these lines at the top of it:

lua
function QBCore.Functions.Notify(text, texttype, length, icon)
    if GetResourceState('lumo-ui') == 'started' then
        return exports['lumo-ui']:Notify(text, texttype, length, icon)
    end
    -- … the original code stays below …

Server notifications (QBCore.Functions.Notify(source, …) on the server, TriggerClientEvent('QBCore:Notify', …)) end in the same function, so this one edit covers them. Re-apply it after updating qb-core.

4. Radial items ​

Copy the items from your old qb-radialmenu/config.lua into config.lua:

  • Config.MenuItems → LumoUiConfig.Radial.Items (same fields: id, title, icon, type, event, shouldClose, items).
  • Config.JobInteractions → LumoUiConfig.Radial.JobItems, keyed by job name. They show in a "Work" submenu while on duty.

The seated vehicle menu (seats, engine, doors, extras) is built in; LumoUiConfig.Radial.VehicleMenu turns its parts on or off. Scripts that call exports['qb-radialmenu']:AddOption(...) keep working through the shim.

5. Affected resources ​

ResourceWhat to do
qb-smallresourcesNothing. Its seatbelt and cruise events are read by the HUD.
qb-policejob, qb-ambulancejob, qb-mechanicjob, …Nothing. They use qb-target, qb-menu, qb-input and progressbar through the shims.
Fuel (LegacyFuel, cdn-fuel, ps-fuel, lc_fuel, ox_fuel)Nothing. Found automatically (LumoUiConfig.Hud.Fuel = 'auto').
Stress (hud:server:GainStress / RelieveStress)Nothing. Same events and the same metadata.stress as qb-hud.
Scripts using ox_lib's UI directly (lib.notify, lib.progressBar, lib.registerContext, lib.inputDialog)ox_lib keeps drawing those. Lumo UI does not replace ox_lib.

Qbox ​

Qbox is built on ox_lib and ox_target, and most qbx_* resources call them directly. Lumo UI does not replace ox_lib or ox_target: Qbox needs both. So on Qbox, Lumo UI gives you the HUD, the radial, Lumo notifications and the qb-* compatibility, and ox_target stays your target eye.

1. Move these folders to [disabled] ​

Old resourceReplaced by
qbx_hud (or qb-hud, ps-hud, any HUD)lumo-ui HUD
qbx_radialmenu (optional, see step 5)lumo-ui radial

Keep ox_lib and ox_target.

2. Turn off Lumo's target eye ​

ox_target and Lumo's eye both open on Left Alt. In lumo-ui/config.lua:

lua
LumoUiConfig.Target = {
    Enabled = false,
    -- …
}

and delete [compat]/qb-target: ox_target already answers exports.qtarget:*. Scripts written only for exports['qb-target'] need their target calls changed to ox_target (most popular scripts have an ox_target option in their config).

3. server.cfg ​

cfg
ensure ox_lib
ensure oxmysql
ensure qbx_core
ensure ox_target
ensure lumo-ui
ensure lumo-interact
ensure lumo-chat-theme   # after chat
# Only for older qb-* scripts that call these resources by name:
ensure qb-menu
ensure qb-input
ensure progressbar

qb-menu, qb-input and progressbar are not part of Qbox. Ensure their shims only if you run older scripts that need them (the console then shows Could not find dependency qb-menu or No such export ShowInput).

4. Notifications (two edits in qbx_core) ​

qbx_core sends every notification to ox_lib. To have lumo-ui draw them:

qbx_core/client/functions.lua, in function Notify(...), just before the lib.notify({ line:

lua
    if GetResourceState('lumo-ui') == 'started' then
        local message = (title and description) and { text = description, caption = title } or description or title
        return exports['lumo-ui']:Notify(message, notifyType == 'inform' and 'info' or notifyType, duration, notifyIcon)
    end
    lib.notify({

qbx_core/server/functions.lua, in function Notify(source, ...), just before the TriggerClientEvent('ox_lib:notify', source, { line:

lua
    if GetResourceState('lumo-ui') == 'started' then
        local message = (title and description) and { text = description, caption = title } or description or title
        return TriggerClientEvent('lumo-ui:client:notify', source, message, notifyType == 'inform' and 'info' or notifyType, duration)
    end
    TriggerClientEvent('ox_lib:notify', source, {

Without these edits nothing breaks: ox_lib keeps drawing Qbox notifications. Re-apply them after updating qbx_core.

5. Radial menu: pick one ​

  • Keep qbx_radialmenu: set LumoUiConfig.Radial.Enabled = false.
  • Use Lumo's radial: move qbx_radialmenu to [disabled] and copy its menu items into LumoUiConfig.Radial.Items / JobItems (see the QBCore step 4 for the fields). Items that other scripts add with lib.addRadialItem still go to ox_lib's own radial menu, not Lumo's.

6. Affected resources ​

ResourceWhat to do
QBCore.Functions.Progressbar (Qbox bridge)Nothing. Qbox draws it with ox_lib's progress bar.
qbx_* resources (garages, police, ambulance, …)Nothing. They keep using ox_lib and ox_target.
qbx_seatbelt, ox_fuelNothing. The HUD reads the seatbelt events and ox_fuel's fuel state bag.
StressNothing. Read from metadata.stress, as on QBCore.
Scripts using lib.progressBar, lib.registerContext, lib.inputDialog, lib.showTextUIox_lib keeps drawing those. Lumo UI does not replace ox_lib.

ESX Legacy ​

ESX has no target eye, no radial and no HUD of its own, so Lumo UI adds those, and the ESX shims make ESX's own notifications, progress bar and key prompts use the Lumo look.

1. Move these folders from [core] to [disabled] ​

Old resource (in [core])Replaced byShim to ensure
esx_notifylumo-ui notificationsesx_notify
esx_progressbarlumo-ui progress baresx_progressbar
esx_textuilumo-ui key promptsesx_textui
any HUD (esx_hud, …)lumo-ui HUD—

Keep these ESX resources running, Lumo UI does not replace them:

  • esx_menu_default, esx_menu_dialog, esx_menu_list (ESX.UI.Menu): the job, shop and boss menus of many ESX scripts use them.
  • esx_context (ESX.OpenContext).

2. Target eye: pick one ​

  • No target script yet: use Lumo's eye. Ensure the qb-target shim too, so scripts with a "qtarget" or "qb-target" option work with it.
  • You already run ox_target: keep it, set LumoUiConfig.Target.Enabled = false in lumo-ui/config.lua, and delete [compat]/qb-target (ox_target already answers exports.qtarget:*).

3. server.cfg ​

ESX's recipe ensures the whole [core] folder, so the order matters: Lumo UI and its shims go right after es_extended, before [core].

cfg
ensure oxmysql
ensure ox_lib            # if you use it
ensure es_extended
ensure lumo-ui
ensure lumo-interact
ensure lumo-chat-theme   # after chat
ensure esx_notify
ensure esx_progressbar
ensure esx_textui
ensure qb-target         # only with Lumo's target eye (step 2)
ensure [core]
ensure [standalone]
ensure [esx_addons]

No code edits are needed on ESX: ESX.ShowNotification, ESX.Progressbar, ESX.TextUI and ESX.HideUI look for these resource names and find the shims.

4. Radial items ​

ESX has no radial menu, so it starts with the product items (Emotes, Clothing) and the seated vehicle menu. Add your own in LumoUiConfig.Radial.Items and per job in LumoUiConfig.Radial.JobItems:

lua
LumoUiConfig.Radial.Items = {
    -- type 'command' runs a chat command, 'client' / 'server' trigger an event
    { id = 'emotes', title = 'Emotes', icon = 'face-smile', type = 'command', event = 'emotes', shouldClose = true },
}
LumoUiConfig.Radial.JobItems = {
    police = {
        { id = 'mdt', title = 'MDT', icon = 'tablet', type = 'client', event = 'yourmdt:client:open', shouldClose = true },
    },
}

Replace the commands and events with the ones your scripts already have.

5. Affected resources ​

ResourceWhat to do
esx_status + esx_basicneedsNeeded for the hunger and thirst bars. Without them those bars stay full.
ESX.UI.Menu / ESX.OpenContext menusNothing. ESX keeps drawing them (step 1).
esx_ambulancejob, cloakroomsNothing for Lumo UI. (If you use Lumo Clothing, it stands in for esx_skin.)
Scripts with a target option ('qtarget', 'qb-target', 'ox_target')Set the option to the target you chose in step 2.
StressSaved in the player's ESX metadata (stress). hud:server:GainStress / RelieveStress work.
FuelFound automatically (LegacyFuel, ox_fuel, …).

Standalone ​

cfg
ensure oxmysql
ensure lumo-ui
ensure lumo-interact
ensure lumo-chat-theme   # after chat

Only add shims for resources your scripts call by name. The HUD shows health, armour, voice, vehicle and minimap; status bars you feed yourself with exports['lumo-ui']:SetStatus('hunger', 80). Notifications: exports['lumo-ui']:Notify(text, type, duration) or the lumo-ui:client:notify event. See API.


After installing ​

  1. Restart the whole server once (not just the resource), so the shims and lumo-ui start in the right order.
  2. In game: press F1 for the radial, hold Left Alt for the target eye, type /ui for settings. Console line on start: [lumo-ui] ready — framework: qb | qbx | esx | standalone.
  3. Later, to restart only the UI, admins run /uirestart: it restarts the shims first, then lumo-ui.
  4. Keys are FiveM key bindings: players change them in Settings → Key Bindings → FiveM. Changing Key / OpenKey in config.lua only changes the default for players who never pressed it.

Troubleshooting ​

You seeCauseFix
Chat still has the default looklumo-chat-theme not ensured, or another chat theme runsEnsure chat, then lumo-chat-theme. If another chat theme runs (for example chat-theme-gtao from [cfx-default]), move it to [disabled] so the two styles do not mix. In F8, restart lumo-chat-theme reloads the style.
Could not find dependency qb-target (or qb-menu, qb-input, progressbar) for a resourceThe shim is not ensuredEnsure that shim after lumo-ui.
No such export AddBoxZone in resource qb-targetThe shim started before lumo-ui, or Target.Enabled = falseEnsure lumo-ui first and restart the server; with the eye off, use ox_target and delete the qb-target shim.
Two target eyes on Left Altox_target and Lumo's eye both runSet LumoUiConfig.Target.Enabled = false, or remove ox_target (not on Qbox).
Two HUDs on screen, or the HUD flickersqb-hud / qbx_hud / ps-hud / esx_hud still runsMove the old HUD to [disabled].
Notifications still look oldFramework routing not setQBCore: the qb-core edit. Qbox: the qbx_core edits. ESX: the esx_notify shim, with [core]/esx_notify moved out. Scripts that call lib.notify directly stay on ox_lib.
ESX progress bar or [E] prompt still looks old[core]/esx_progressbar or [core]/esx_textui still in resources/Move them to [disabled] and ensure the shims.
The old resource starts instead of the shimBoth folders are in resources/Move the original out of resources/ entirely.
Hunger and thirst stay full (ESX)esx_status / esx_basicneeds not runningInstall them, or feed the bars with SetStatus.
Fuel always full, or wrongFuel script not foundSet LumoUiConfig.Hud.Fuel to your fuel resource's name.
Radial does not open on F1F1 is bound by another script, or Radial.Enabled = falseRebind it in Key Bindings → FiveM, or change LumoUiConfig.Radial.Key.
/ui has no Admin tabNo permissionadd_ace group.admin lumo.ui.admin allow, or a group from AdminPermissions.
Item pictures missing in menusInventory images not foundSet LumoUiConfig.Menu.ImagePath to your inventory's image folder, e.g. nui://ox_inventory/web/images/.
Players' /ui layout reset after moving from the Lumo HUDSettings are saved per resource nameExpected once; players set it again.

Still stuck? Open a ticket with your framework, the F8 console error and the resource that called lumo-ui.

Going back ​

Stop lumo-ui, lumo-interact and the shims, move the original resources back from [disabled], undo the notify edits and restore your server.cfg. Nothing in the database is changed, except the stress value Lumo UI shares with qb-hud.