Skip to main content
WindUI’s config system lets you save and restore the state of any flagged UI element to disk. Users can maintain named config presets that survive across hub sessions.
The config system requires a writeable filesystem. It does not function in Roblox Studio or executors that do not expose writefile.

How it works

Every element that has a Flag string is automatically tracked by the window’s ConfigManager. When you call Save() on a config, each tracked element’s current value is serialised to a JSON file under:
WindUI/<Folder>/config/<configName>.json
On Load(), those values are pushed back into each element by calling its own setter (Set, Select, Update, etc.), so callbacks fire as normal.

Saveable element types

ElementSaved field
ToggleValue (boolean)
SliderValue.Default (number)
InputValue (string)
DropdownValue (string or table)
ColorpickerDefault (hex) + Transparency
KeybindValue (string)

Setup

1

Set a Folder name when creating the window

Passing Folder to CreateWindow initialises the ConfigManager and creates the storage directory automatically.
local Window = WindUI:CreateWindow({
    Title = "My Hub",
    Folder = "myhub", -- required for config saving
})
2

Add a Flag to every element you want saved

Any element with a unique Flag string is registered in Window.PendingFlags and picked up automatically on the next Save() or Load().
ConfigElementsTab:Toggle({
    Flag = "ToggleTest",
    Title = "Toggle Panel Background",
    Value = not Window.HidePanelBackground,
    Callback = function(state)
        Window:SetPanelBackground(state)
    end,
})

ConfigElementsTab:Slider({
    Flag = "SliderTest",
    Title = "Slider",
    Step = 1,
    Value = { Min = 20, Max = 120, Default = 70 },
    Callback = function(value)
        print(value)
    end,
})

ConfigElementsTab:Input({
    Flag = "InputTest",
    Title = "Input",
    Value = "Default value",
    Placeholder = "Enter text...",
    Callback = function(input)
        print("Text entered: " .. input)
    end,
})

ConfigElementsTab:Keybind({
    Flag = "KeybindTest",
    Title = "Keybind",
    Value = "G",
    Callback = function(v)
        Window:SetToggleKey(Enum.KeyCode[v])
    end,
})

ConfigElementsTab:Colorpicker({
    Flag = "ColorpickerTest",
    Title = "Colorpicker",
    Default = Color3.fromRGB(0, 255, 0),
    Transparency = 0,
    Callback = function(color)
        print("Color: " .. tostring(color))
    end,
})

ConfigElementsTab:Dropdown({
    Flag = "DropdownTest",
    Title = "Dropdown",
    Values = { "Option A", "Option B", "Option C" },
    Value = "Option A",
    Callback = function(option)
        print("Selected: " .. option)
    end,
})
3

Get the ConfigManager and build the config UI

Window.ConfigManager is available after the window is created. Use ConfigManager:AllConfigs() to enumerate saved configs for the dropdown.
local ConfigManager = Window.ConfigManager
local ConfigName = "default"

local ConfigNameInput = ConfigTab:Input({
    Title = "Config Name",
    Icon = "file-cog",
    Callback = function(value)
        ConfigName = value
    end,
})

ConfigTab:Space()

local AllConfigs = ConfigManager:AllConfigs()
local DefaultValue = table.find(AllConfigs, ConfigName) and ConfigName or nil

local AllConfigsDropdown = ConfigTab:Dropdown({
    Title = "All Configs",
    Desc = "Select existing configs",
    Values = AllConfigs,
    Value = DefaultValue,
    Callback = function(value)
        ConfigName = value
        ConfigNameInput:Set(value)
    end,
})
4

Add Save and Load buttons

ConfigManager:Config(name) creates or retrieves a config by name. Call :Save() to write to disk and :Load() to restore.
ConfigTab:Space()

ConfigTab:Button({
    Title = "Save Config",
    Icon = "",
    Justify = "Center",
    Callback = function()
        Window.CurrentConfig = ConfigManager:Config(ConfigName)
        if Window.CurrentConfig:Save() then
            WindUI:Notify({
                Title = "Config Saved",
                Content = "Config '" .. ConfigName .. "' saved",
                Icon = "check",
            })
        end

        AllConfigsDropdown:Refresh(ConfigManager:AllConfigs())
    end,
})

ConfigTab:Space()

ConfigTab:Button({
    Title = "Load Config",
    Icon = "",
    Justify = "Center",
    Callback = function()
        Window.CurrentConfig = ConfigManager:CreateConfig(ConfigName)
        if Window.CurrentConfig:Load() then
            WindUI:Notify({
                Title = "Config Loaded",
                Content = "Config '" .. ConfigName .. "' loaded",
                Icon = "refresh-cw",
            })
        end
    end,
})
After saving, AllConfigsDropdown:Refresh(...) is called so the dropdown immediately reflects any newly created config files.

ConfigManager API reference

Alias for ConfigManager:CreateConfig(name). Returns a ConfigModule object.
local config = Window.ConfigManager:Config("default")
Creates a config object. If autoload is true, the config is loaded automatically 0.5 seconds after it is created, provided the file already exists on disk.
local config = Window.ConfigManager:CreateConfig("preset1", true)
Collects all flagged element values from Window.PendingFlags, serialises them, and writes the result to WindUI/<Folder>/config/<name>.json. Returns the saved data table.
local data = config:Save()
Reads the config file from disk, migrates legacy formats, and calls each element’s setter via the parser. Returns the custom data table on success, or false, errorMessage on failure.
local customData, err = config:Load()
Deletes the config file from disk and removes the entry from ConfigManager.Configs.
local ok, err = config:Delete()
Returns a list of config names (without .json) found in the config folder.
local names = Window.ConfigManager:AllConfigs()
-- { "default", "preset1", "preset2" }
Returns a Lua array of config name strings for all configs that have AutoLoad = true in the current session.
local autoConfigs = Window.ConfigManager:GetAutoLoadConfigs()
-- { "default", "preset1" }
Returns the in-memory ConfigModule for a given config name, or nil if it has not been created in this session.
local config = Window.ConfigManager:GetConfig("default")
Deletes a config file by name without requiring a ConfigModule reference.
local ok, err = Window.ConfigManager:DeleteConfig("old-preset")
Store and retrieve arbitrary custom data alongside element state.
config:Set("myKey", "someValue")
local val = config:Get("myKey") -- "someValue"
Override the default storage path. The path must end with / or one is appended automatically.
Window.ConfigManager:SetPath("WindUI/custom-folder/configs/")

Auto-load

Set autoload = true in CreateConfig (or call config:SetAutoLoad(true) before saving) and the config will be restored automatically on the next session, 0.5 s after the config object is created.
local config = Window.ConfigManager:CreateConfig("default", true)
config:Save()
-- On the next run, values are restored automatically
Auto-load reads and applies values 0.5 seconds after CreateConfig is called. Make sure all flagged elements exist in the UI before that point, or their values will not be restored.

Build docs developers (and LLMs) love