Roblox UI,
done properly.
Roblox UI is usually a mess of global variables and unorganized frames.
SlateUI is a modular, event-driven framework built for developers who care about code quality.
7
Services
0
Global variables
1
require() to start
Architecture
Under the Hood
Three structural decisions that make SlateUI maintainable at scale — not just in demos.
Zero Global Pollution
Every component is a self-contained object returned from a constructor. Event connections are stored internally and torn down in a single .Destroy() call. Nothing leaks into _G, shared, or ReplicatedStorage by default.
-- Create local slider = InputsService.Slider(frame, cb) -- Destroy — disconnects everything slider:Destroy()
Router-Driven Navigation
RouterService manages independent navigation groups. Calling Navigate() closes the previous view and opens the next one with a configurable tween. No manual Visible toggling. No z-index fights. No spaghetti.
RouterService.RegisterView("HUD", "Map", mapFrame)
RouterService.Navigate("HUD", "Map")
-- Previous view auto-closesSingle-Source Theme
Color palettes and tween parameters live in one place inside each service module. Changing DefaultColor in ButtonService immediately affects every button in the game. No hunting through LocalScripts for hardcoded RGB values.
-- In ButtonService.luau
local THEMES = {
primary = {
DefaultColor = Color3.fromRGB(71, 85, 105),
HoverColor = Color3.fromRGB(61, 74, 91),
-- edit once, applies everywhere
},
}Real-world proof
Not just another UI kit.
Here is what the same problem looks like before and after SlateUI. No benchmarks — just code.
| Topic | Standard Roblox Workflow | SlateUI Workflow | |
|---|---|---|---|
| Navigation | Manually toggle .Visible on each frame, no state tracking | → | RouterService.Navigate() — closes old, opens new, fires callbacks |
| Animations | Copy-pasted TweenService calls scattered across dozens of scripts | → | Centralized tween parameters per service, one edit propagates everywhere |
| Input handling | UserInputService listeners in random LocalScripts, rarely cleaned up | → | InputsService attaches and disconnects on AncestryChanged automatically |
| Theming | Hardcoded Color3 values duplicated across every button and frame | → | THEMES table in ButtonService — one RGB change updates the entire game |
| Notifications | Custom RemoteEvent per feature, no standard animation or lifetime | → | NotificationService client/server API, auto-dismiss, 4 built-in statuses |
| Cleanup | Connections leak; instances stay in memory after the GUI is destroyed | → | :Destroy() disconnects every connection and removes the frame |
| Proximity UI | Per-part scripts with duplicated distance checks on every Heartbeat | → | ProximityService.Init() — tag once, hysteresis + dot-product handled |
Show, don't tell
Live components
Every animation is driven by the same logic that runs in your game. Not CSS simulations.
Smooth Slider
Spring-physics knob. Zero jitter at boundary.
Switch Toggle
Instant state flip with layout-animated knob.
Proximity UI
Unfurls on approach. Hysteresis prevents flicker.
Notifications
Client or server. Four statuses. Auto-dismiss.
Get started
One plugin. Five minutes.
Install the plugin, require the services, and write less Roblox UI code from now on. The docs cover every service with quick-start and advanced examples.