Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sure-developer.com/llms.txt

Use this file to discover all available pages before exploring further.

LUI

lui is the client-side Lua UI module added in sure_lib 2.2.x. It renders Lua node trees into the bundled NUI renderer at web/lui/index.html, routes NUI events back into Lua callbacks, and re-renders when tracked state changes.
local lui = sure.getModule('lui')
local track = sure.getModule('track')

fxmanifest setup

Any resource that opens LUI pages should use the sure_lib renderer as its ui_page.
fxmanifest.lua
ui_page 'https://cfx-nui-sure_lib/web/lui/index.html'

shared_script '@sure_lib/init.lua'
client_script 'client.lua'

dependencies {
  'ox_lib',
  'sure_lib'
}
Enable renderer debug traces with ?luiDebug=1 or localStorage.setItem('sure:lui:debug', '1') in NUI DevTools.

Builder pages

lui.page(pageId, function(ui) ... end, props?) renders immediately and stores the page. Use lui.open(pageId) and lui.close(pageId) to control NUI focus and visibility.
client.lua
local count, setCount = track.state('count', 0)

lui.page('counter', function(ui)
  ui.panel({
    className = 'w-[360px]'
  }, function()
    ui.typography('Counter', {
      variant = 'h2'
    })
    ui.text(count)
    ui.button('Increment', function()
      setCount(function(value)
        return value + 1
      end)
    end, {
      iconComponent = 'lucide:plus'
    })
  end)
end, {
  font = 'Inter, sans-serif',
  theme = {
    ink = '#ffffff',
    muted = '#d4d4d8'
  }
})

lui.open('counter', {
  focus = true,
  cursor = true
})

Declarative node trees

LUI also exposes factories directly on lui, so larger interfaces can be split into component functions.
local function Header(title)
  return lui.panel({
    className = 'header'
  }, {
    lui.text(title),
    lui.button('Close', function()
      lui.close('dashboard')
    end, {
      endIconComponent = 'lucide:x'
    })
  })
end

lui.page('dashboard', lui.stack({
  className = 'page'
}, {
  Header('Dashboard'),
  lui.row({}, {
    lui.badge('Live', {
      iconComponent = 'lucide:activity'
    }),
    lui.typography('Ready', {
      variant = 'muted'
    })
  })
}))

Reactive rendering

Tracked values can be passed directly into text, typography, inputs, selects, sliders, tables, lists, and other node props. LUI records dependencies while building the page and sends patches when those states change.
local items, setItems = track.state('items', {
  {
    id = 'bread',
    label = 'Bread'
  }
})

lui.page('inventory', function(ui)
  ui.foreach(items, function(item, index, itemUi)
    itemUi.text(index .. ': ' .. item.label)
  end, {
    keyBy = 'id'
  })
end)

setItems(function(current)
  current[#current + 1] = {
    id = 'water',
    label = 'Water'
  }

  return current
end)

Page API

lui.page(pageId, pageBuilder, props?)
function
required
Registers and renders a page. pageBuilder may be a callback builder or a declarative node tree.
lui.render(pageId)
function
Re-renders an existing page and sends patches when the tree changed.
lui.open(pageId, focusOptions?)
function
Marks a page visible, renders it, sends a visibility message, and calls SetNuiFocus.
lui.close(pageId)
function
Marks a page hidden, clears NUI focus, and sends a visibility message.

Components

Component docs are split by the renderer source folders under ui/lui/src/components, with one page per public component.

Primitives

Text rendering for short paragraph content.

Controls

Button, Input, Select, Slider, and Textarea.

Display

Accordion, Alert, Badge, Table, and Typography.

Layout

Panel, Row, and Stack containers.

Motion

MotionNode and Presence for animated UI.

Navigation and Overlay

Carousel, Tabs, and Tooltip.
stack, row, and panel create layout containers. Common props include className, classBase, gap, align, width, font, and theme.
button, input, select, textarea, and slider support event callbacks through onPress or onChange. Callback payloads are passed from NUI to Lua.
alert, badge, typography, accordion, tabs, table, carousel, and tooltip cover common shadcn-like UI surfaces.
presence, animatePresence, motion, motionDiv, motionRow, motionStack, motionList, motionListItem, motionItem, motionSection, motionButton, and motionText forward animation props such as initial, animate, exit, whileTap, layout, and transition.
Builder pages support when, ifElse, unless, and foreach. Declarative pages support lui.list(source, render, props?), lui.fragment(children), and lui.component(component, ...).

Icons and styling

LUI supports text icons and Iconify-style icon component names.
ui.button('Save', function() end, {
  icon = {
    name = 'lucide:save',
    width = 16
  },
  endIcon = '->'
})

ui.badge('Ready', {
  iconComponent = 'lucide:check'
})
Several composed components preserve part-specific class props, such as triggerClassName, menuClassName, activeOptionClassName, rangeClassName, thumbClassName, contentClassName, titleClassName, and active tab class props.
The bundled renderer includes controls, display components, motion helpers, runtime utility classes, and Iconify-powered Lucide icons, so consuming resources can describe UI from Lua without writing HTML.