Fragment is a simple module I made to manage Roblox's imperative UI instance system inspired by React. It currently supports state management, effects, declarative rendering, globals stores, re-usable components which allow you to build reactive user interfaces whilst still using default Roblox's UI components.
To learn more or get more details on the installation and available methods, read the docs here.
- Insert a ModuleScript named
FragmentintoReplicatedStorage. - Paste the source code of Fragment into the ModuleScript you just created.
- Created a folder for your UI (e.g.,
MySuperDuperUI) somwehere like inStarterPlayerScripts.
And there you go, you got Fragment in your project! π£οΈ
Once you installed Fragment and created the folder (e.g., MySuperDuperUI), you may now start using it. For your projects, I recommend using this structure:
.
βββ StarterPlayerScripts/
βββ MySuperDuperUI/
βββ FragmentLoad.client.luau -- This will be used to init a Fragment singleton instance
βββ Components/
β βββ ...
βββ Handles/
β βββ ...
βββ Hooks/
β βββ ...
βββ Stores/
βββ ...
Now, in FragmentLoad.client.luau :: LocalScript you can now directly require the Fragment ModuleScript you installed and load your handles.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Fragment = require(ReplicatedStorage.Fragment)
-- Load all your modulescripts here!
Fragment.load({
Stores = script.Parent.Stores,
Contexts = script.Parent.Contexts,
Hooks = script.Parent.Hooks,
Components = script.Parent.Components,
Handles = script.Parent.Handles,
})That's it! You can see a bit of the API references and some examples in this readme or you can head to the Github Wiki to find out how it works in details.
Fragment runs as a singleton across your whole client and can be required everywhere in your Handles, Stores, Hooks and Contexts.
Handles bind logic to specific UI instances. They are created using Fragment.newHandle and define a Rendered Function that runs whenever the state of your handle changes.
local Handle = Fragment.newHandle("MyButton", { "ScreenGui", "Frame", "TextButton" })
return Handle(function(Element: TextButton)
element.Text = "Click me"
Handle.Connect("Click", element.Activated, function()
print("Button clicked")
end)
endYou can manage your local handle's state similar to React's useState hook.
local count, setCount = Handle:bind(0)
Handle.Connect("Increment", button.Activated, function()
setCount(count() + 1)
end)
element.Text = `Count: {count()}`You can also create centralized state management stores accessible across multiple handles.
-- Definition
return Fragment.createStore("PlayerData", function(set, get)
return {
Coins = 0,
addCoins = function(amount: number)
set({ Coins = get().Coins + amount })
end
}
end)
-- Usage in a Handle
local store = Fragment.useStore("PlayerData")
element.Text = `Coins: {store.Coins}`This way of creating stores is really similar to Zustand (for React), and I did inspire myself from it to make this.
You can share logic between handles using what's called Contexts and Composable functions.
-- New Context
local WindowContext = Fragment.createContext({ active = nil })
-- Custom Hook
local useWindow = Fragment.compose(function(handle, windowName)
local ctx = handle:pull(WindowContext)
local isOpen = handle:derive(function()
return ctx.active == windowName
end, { ctx.active })
return isOpen, ctx
end)You can finally create re-usable components you can call through your different handles.
-- New Component
local Component = Fragment.newComponent("ListItem", { "ScreenGui", "Assets", "ListItem" })
return Component(function(element, props)
element.Text = props.Price
end)local Handle = Fragment.newHandle(..., ...)
return Handle(function(element)
local Store = Fragment.useStore(...)
local Data = Store.getData()
local Container = Handle.RegisterContainer(...)
for _, entry in Data.Entries do
local Item = Fragment.useComponent(name, { Price = math.random() }) -- Automatically returns a clone
local live = Container.UpsertChild(Item)
-- ...
end
end)You can pretty much use Fragment for anything. In my case, I use it with ReplicaService and Knit. I really like react and since most of the people I work with don't use it's luau version and bake the UI directly using Roblox's Studio interface manager (if I may call it like that), I thought it would be pretty cool to have such a ressource out there; maybe there's other more complete frameworks for that on roblox but I didn't find any so, here it is.
Again, if you wanna know how things work in more details, check out the Github Wiki for API references and usage examples. Peace!