< Back 
roblox ui library

PrettyUI

Attribute-driven Roblox UI library. Hover effects, open/close animations, sound feedback, GUI stacking with blur, and selection groups with zero per-button scripting.

Luau Roblox UI
Take a look ↗

Zero-code UI, driven by attributes.

PrettyUI is a lightweight Roblox UI library that handles hover effects, open/close animations, sound feedback, GUI stacking with blur, and selection groups, configured entirely through instance attributes in Studio, with zero per-button scripting.

⚠️ PrettyUI is in an early experimental stage. Expect bugs. Contributing is as easy as opening an issue or a pull request.

Features

  • Zero-code configuration: set up buttons, sounds, and navigation entirely through instance attributes in Studio
  • Automatic registration: any ScreenGui tagged PManagedGUI = true is picked up on load and dynamically at runtime
  • Stack-based GUI management: opening a GUI pushes it onto a stack; closing restores the one behind it, with a smooth global blur
  • PButton: hover scale animation, cursor glow effect, sound hooks, and click-to-navigate between GUIs
  • PSelectionGroup: single or multi-select button groups with animated selection images
  • Event modules: attach OnClicked, OnHover, etc. as child ModuleScripts directly on your buttons, no central handler needed
  • Janitor-backed cleanup: every component cleans up its own connections and tweens automatically

Requirements

PrettyUI depends on two packages under ReplicatedStorage/Packages/:

PackageSource
Promiseevaera/promise on Wally
Janitorhowmanysmall/janitor on Wally

Installation

  1. Copy the Pretty folder into StarterPlayer/StarterPlayerScripts.
  2. Make sure Janitor and Promise are present under ReplicatedStorage/Packages/.
  3. Call :Init() then :Start() from your client bootstrap:
local Pretty = require(path.to.Pretty)
Pretty:Init()
Pretty:Start()

Pretty scans PlayerGui on start and watches for new ScreenGuis added at runtime with no extra wiring needed.

GUI Structure

Every managed ScreenGui must follow this hierarchy:

ScreenGui            ← attribute: PManagedGUI = true
└── Canvas           ← Frame (AnchorPoint 0.5, 0.5), animated in/out
    └── Container    ← Frame, put your actual UI content here
        ├── ImageButton        ← becomes a PButton automatically
        ├── ImageButton
        └── CanvasGroup        ← becomes a PSelectionGroup (needs PSelectionGroup = true)
            ├── ImageButton
            └── ImageButton

Canvas slides between (0.5, 0, 0.5, 0) (open) and (0.5, 0, 1.5, 0) (closed). The ScreenGui starts disabled, Pretty enables it after the initial toggle resolves.

Design Notes

Navigation between GUIs, selection groups, and close behavior are all wired through attributes (POpensGUI, PClosesCurrentGUI, PAddsToStack, PSelectionGroup, etc.). Event logic lives in child ModuleScripts named after the event (OnClicked, OnHover, OnSelect) keeping every button self-contained and the codebase free of central handlers.


Licensed under the MIT License - Copyright (c) 2026 Mastedore.