Docs/Nova UI
Drawing library · v1.0.0

Nova UI Library

A dependency-free Drawing library with multiple windows, drag and resize, responsive columns, search, eleven control types, themes, dialogs, notifications, and portable JSON state.

Install

One HTTPS request

Enable the individual HttpGet permission first. The source returns the library table and also exposes it as getgenv().NovaUI. Loading it again cleans up the previous instance first.

Lua 5.4
-- Enable HttpGet in LuaVM > Settings > Security first.
local NovaUI = loadstring(game:HttpGet(
    "https://externals.gg/scripts/nova-ui.lua"
))()
LuaVM permissions

Downloading needs HttpGet. Interactive windows additionally need getinputstate, iskeydown, getmouseposition, and ismouse1pressed. Enable only the workspace permissions used by config save, load, delete, or listing.

Learn by building

Small examples, one idea each.

These examples assume Nova UI is loaded with the install snippet above. Open the pattern you need, then follow its API link for every available option.

Build your first windowCreate a window, add a page and section, then place two stateful controls.

What this teachesCreateWindow · tabs · sections · toggle · slider

first-window.lua
local Window = NovaUI:CreateWindow({
    Title = "My tool",
    Subtitle = "Built with Nova UI",
    Size = Vector2.new(680, 460),
    Keybind = "Insert"
})

local Main = Window:AddTab({ Title = "Main" })
local General = Main:AddSection({ Title = "General" })

General:AddToggle({
    Title = "Enabled",
    Description = "Controls the main feature",
    Id = "enabled",
    Default = false
})

General:AddSlider({
    Title = "Range",
    Id = "range",
    Min = 25,
    Max = 500,
    Default = 150,
    Suffix = " studs"
})
Open related API
Connect controls to behaviorReact to a value, disable another control and read shared state by ID.

What this teachesOnChanged · GetValue · SetDisabled · notifications

reactive-controls.lua
local Enabled = General:AddToggle({
    Title = "Enabled",
    Id = "enabled",
    Default = false
})

local Strength = General:AddSlider({
    Title = "Strength",
    Id = "strength",
    Min = 1,
    Max = 10,
    Default = 5
})

Enabled:OnChanged(function(value)
    Strength:SetDisabled(not value)
    Window:Notify({
        Title = value and "Enabled" or "Disabled",
        Content = "Strength is " .. Strength:GetValue(),
        Type = value and "Success" or "Info"
    })
end)

print(Window:GetValue("enabled"), Window:GetValue("strength"))
Open related API
Ask, confirm and respondPresent a two-action dialog and turn the result into visible feedback.

What this teachesDialog · buttons · callbacks · notification types

dialog-flow.lua
Window:Dialog({
    Title = "Apply this profile?",
    Content = "The current control values will be replaced.",
    Buttons = {
        { Title = "Apply", Value = "apply" },
        { Title = "Cancel", Value = "cancel" }
    },
    Callback = function(value)
        if value == "apply" then
            Window:Notify({
                Title = "Profile applied",
                Content = "Every linked control is up to date.",
                Type = "Success"
            })
        end
    end
})
Open related API
Complete example

Window, controls, input, and feedback

Every stateful control can use an Id or Flag. Values appear in both Window.Flags and NovaUI.Flags.

my-tool.lua
-- Enable HttpGet and the four input-state permissions first.
local NovaUI = loadstring(game:HttpGet(
    "https://externals.gg/scripts/nova-ui.lua"
))()

local Window = NovaUI:CreateWindow({
    Title = "My Nova tool",
    Subtitle = "External control panel",
    Size = Vector2.new(760, 540),
    Theme = "Nova",
    Keybind = "Insert",
    ConfigFolder = "my-tool"
})

local Main = Window:AddTab({ Title = "Main" })
local Targeting = Main:AddSection({ Title = "Targeting", Column = "left" })
local Appearance = Main:AddSection({ Title = "Appearance", Column = "right" })

Targeting:AddToggle({
    Title = "Enabled",
    Description = "Run the frame logic",
    Id = "enabled",
    Default = false,
    Callback = function(value)
        print("Enabled:", value)
    end
})

Targeting:AddSlider({
    Title = "Range",
    Id = "range",
    Min = 25,
    Max = 500,
    Default = 150,
    Rounding = 0,
    Suffix = " studs"
})

Targeting:AddDropdown({
    Title = "Priority",
    Id = "priority",
    Values = { "Crosshair", "Distance", "Low health" },
    Default = "Crosshair"
})

Targeting:AddKeybind({
    Title = "Activation",
    Id = "activationKey",
    Default = "F4",
    Mode = "Hold",
    OnTriggered = function(active)
        print("Key active:", active)
    end
})

Appearance:AddColorPicker({
    Title = "Accent",
    Id = "accent",
    Default = Color3.fromRGB(242, 97, 115)
})

Appearance:AddInput({
    Title = "Profile name",
    Id = "profile",
    Placeholder = "default",
    MaxLength = 32
})

Appearance:AddButton({
    Title = "Show notification",
    Callback = function()
        Window:Notify({
            Title = "Saved",
            Content = "Your controls are ready.",
            Type = "Success"
        })
    end
})

NovaUI:Notify({
    Title = "Nova UI loaded",
    Content = "Press Insert to toggle the window.",
    Duration = 5
})
State

Export, import, and workspace configs

Color values are serialized safely. Each workspace read, inspection, write, listing, or deletion requires its matching LuaVM permission and remains confined to Nova's workspace.

Configuration
local json = Window:ExportState()
print(json)

-- Configs use separate isfolder, makefolder, writefile, readfile,
-- delfile, and listfiles permissions under LuaVM Security.
local saved, saveError = Window:SaveConfig("default")
if not saved then warn(saveError) end

local loaded, loadError = Window:LoadConfig("default")
if not loaded then warn(loadError) end

-- Or debounce saves after every control change:
Window:EnableAutoSave("default", 1.5)
Multi-windowIndependent position, size, theme, search, tabs, flags, and config scope.
Real interactionTop-window pointer routing, title dragging, resize handles, sliders, scrollbars, and keyboard input.
Clean teardownEvery drawing and frame connection is removed on Destroy, Stop, or reload.
Reference

API reference

Open a category or search for an exact class, datatype, function, property, or method.

LibraryTop-level lifecycle, window, theme, notification, and dialog functions.10
NovaUI:CreateWindow(config) -> Window

Creates an independent draggable, resizable, searchable Drawing window. Alias: Window.

NovaUI:AddTheme(name, colors)

Registers a theme by merging color overrides with the Nova base theme.

NovaUI:Notify(config) -> Notification

Shows a timed info, success, warning, or error card with optional action and progress.

NovaUI:Dialog(config) -> Dialog

Shows a modal with up to three custom actions.

NovaUI:Confirm(config) -> Dialog

Convenience confirm/cancel dialog.

NovaUI:GetWindow(title) -> Window?

Finds a live window by title.

NovaUI:ToggleAll(visible?)

Sets all windows visible or toggles each when no argument is supplied.

NovaUI:SetNotificationPosition(Vector2)

Moves the notification stack anchor.

NovaUI:Destroy()

Disconnects the render loop and removes every drawing. Alias: Unload.

NovaUI.Themes / NovaUI.Flags / NovaUI.Windows

Built-in themes, shared flag values, and live window collection.

WindowManage pages, appearance, search, values, and persistent state.12
Window:AddTab(config) -> Tab

Adds a sidebar tab. Alias: Tab.

Window:SelectTab(tab | title | index)

Selects one of the window's tabs.

Window:SetTheme(name | colors)

Applies a built-in or custom theme to the window.

Window:SetVisible(bool) / Toggle() / Minimize(bool?)

Controls window visibility and compact header mode.

Window:SetPosition(Vector2) / SetSize(Vector2) / SetScale(number)

Moves, resizes, or changes the window canvas scale.

Window:GetValue(id) / SetValue(id, value, silent?)

Reads or changes any ID/Flag-backed control.

Window:Search(query)

Filters sections and controls without switching tabs.

Window:ExportState() / ImportState(json | table, silent?)

Serializes or restores ID-backed values, including Color3 values.

Window:SaveConfig / LoadConfig / DeleteConfig / ListConfigs

Persists JSON under nova-ui/<ConfigFolder> in Nova's workspace.

Window:EnableAutoSave(name, delay?) / DisableAutoSave()

Debounces workspace config writes after control changes.

Window:Notify(config) / Dialog(config)

Window-themed top-level notification and dialog shortcuts.

Window:Destroy()

Removes one window and all of its drawings.

Tabs and sectionsCompose a responsive one- or two-column interface.13
Tab:AddSection(config) -> Section

Creates a card. Set Column to left/right or 1/2; automatic placement balances columns.

Tab:AddToggle(...) and other Add* methods

Controls may be added directly to a tab; Nova UI creates a default section.

Section:AddLabel(config)

Adds mutable single-line text.

Section:AddParagraph(config)

Adds a title and compact supporting text.

Section:AddDivider(config)

Adds a separator with an optional label.

Section:AddButton(config)

Adds a callback button with a programmatic Press method.

Section:AddToggle(config)

Adds a boolean switch.

Section:AddSlider(config)

Adds a bounded drag slider with Min, Max, Rounding, and Suffix.

Section:AddDropdown(config)

Adds a single-select list with Values and MaxVisible.

Section:AddMultiDropdown(config)

Adds a multi-select list whose value is a selected-name map.

Section:AddInput(config)

Adds text or numeric keyboard input with placeholder, maximum length, and finished-only callbacks.

Section:AddKeybind(config)

Adds Toggle, Hold, or Always key activation with OnTriggered.

Section:AddColorPicker(config)

Adds an RGB picker and hexadecimal value preview.

Control methodsEvery stateful control shares a small predictable API.10
Control:GetValue() / SetValue(value, silent?)

Reads or changes the current value and updates its ID-backed flag.

Control:OnChanged(callback)

Adds another change listener without replacing the original callback.

Control:SetVisible(bool) / SetDisabled(bool)

Changes layout visibility or interaction state.

Control:SetDescription(text)

Updates supporting text used by the control and search.

Control:Destroy()

Removes the control from rendering and interaction.

Dropdown:SetValues(values) / Select(value)

Replaces options or selects/toggles an option.

Keybind:SetKey(key) / IsActive()

Changes a virtual key or reads its mode-driven active state.

ColorPicker:SetColor(Color3)

Color-specific SetValue alias.

Label:SetText / Paragraph:SetText

Updates displayed copy.

Button:Press()

Invokes the button callback unless disabled.