Skip to content

Framework Compatibility

Compatibility matrix for ox_lib, ESX, QBCore and QBox. Migration snippets and known incompatibilities.

2 min read

LastMenu is framework-agnostic: it has zero dependencies on ESX, QBCore, or ox_lib. All interactions go through the public exports API.

Compatibility matrix

Featureox_libESX (legacy + v2)QBCore / QBox
Context menu replacement✅ Drop-in✅ Drop-in✅ Drop-in
Input dialog replacement✅ Drop-in✅ Drop-in✅ Drop-in
Notification replacement✅ Drop-in✅ Drop-in✅ Drop-in
Alert / confirm dialog✅ Drop-in✅ Drop-in✅ Drop-in
Radial menu✅ Drop-in✅ Drop-in✅ Drop-in
Progress bar✅ Drop-in✅ Drop-in✅ Drop-in
Target system⚠️ Parallel⚠️ Parallel✅ Native

⚠️ Parallel — ox_target and ESX’s native targeting can coexist with LastMenu’s target system without conflict, but register zones in only one system per resource to avoid duplicate action menus.


Migration snippets

From ox_lib → LastMenu

-- ox_lib context menu
lib.showContext('my_menu')

-- LastMenu
exports.LastMenu:context(function(menu)
    menu:title("My Menu")
    menu:button("Action", { cb = function() end })
end)
-- ox_lib input dialog (blocking)
local result = lib.inputDialog("Title", { { type = "input", label = "Name" } })

-- LastMenu (blocking — must be inside Citizen.CreateThread)
Citizen.CreateThread(function()
    local values = exports.LastMenu:input_async(function(b)
        b:title("Title")
        b:field("Name", {})
        b:confirm_label("OK")
        b:cancel_label("Cancel")
    end)
    if values then print(values[1]) end
end)
-- ox_lib notify
lib.notify({ title = "Info", description = "Hello", type = "inform" })

-- LastMenu
exports.LastMenu:notify(function(n)
    n:title("Info")
    n:message("Hello")
    n:type("info")
end)

From ESX → LastMenu

-- ESX menu (legacy)
ESX.UI.Menu.Open("default", GetCurrentResourceName(), "my_menu", { ... })

-- LastMenu
exports.LastMenu:context(function(menu)
    menu:title("My Menu")
    -- add items here
end)
-- ESX input dialog
ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "input", {
    title = "Name", inputs = { { type = "text", label = "Name" } }
}, function(data, menu) menu.close() end, function(_, menu) menu.close() end)

-- LastMenu
exports.LastMenu:input(function(form)
    form:title("Name")
    form:field("Name", {})
    form:confirm("OK", function(values) print(values[1]) end)
    form:cancel("Cancel")
end)

From QBCore → LastMenu

-- QBCore menu
QBCore.Functions.QBCallback("qb-menu:client:openMenu", false, items)

-- LastMenu
exports.LastMenu:context(function(menu)
    menu:title("Menu")
    for _, item in ipairs(items) do
        menu:button(item.header, {
            cb = item.params.event and function()
                TriggerEvent(item.params.event, item.params.args)
            end,
        })
    end
end)

Known incompatibilities

IssueAffected frameworksWorkaround
ox_target zones and LastMenu target registered on the same entityox_lib + LastMenuRegister in one system only per resource
ESX legacy hideUI conflicts with SetNuiFocus(false) on menu closeESX legacyLet LastMenu manage NUI focus — do not call hideUI while a LastMenu menu is open
QB-Core’s QBCore.Functions.Progressbar running simultaneously with LastMenu progressQBCoreUse LastMenu progress exclusively; QB-Core’s bar renders on a different DOM layer and may overlay

Tested versions

FrameworkVersion testedStatus
ox_lib3.x✅ Compatible
ESX Legacy1.9.x✅ Compatible
ESX v2 (es_extended)2.x✅ Compatible
QBCore1.x✅ Compatible
QBox (qbx_core)latest⚠️ Untested — expected compatible