(forked from an account that no longer exists, named "ccreaper", a synapse developer if I remember correctly)
isu: a minimal, lightweight library for building reactive user interfaces in the Roblox engine.
- isu is minimal. Building and rendering reactive components can be done with an extremely minimal number of calls.
- isu is portable.
isu
implements a complete reactive library in a single, portable, and documented file that can be imported anywhere into your game or script, complete with EmmyLua annotations for IDE use. When minified,isu
goes below 8kb. - isu is functional. Its component library closely aligns with React's hooks and functional components, featuring familiar functions such as
useState
anduseEffect
that allows you to build components without classes (or class-like behavior). - isu is extensible. Whereas other reactive libraries often restrict themselves to native Instances, you can use isu's own component builder to apply reactivity to anything by creating a component builder with
isu.builder
. - isu has batteries included. It comes prepacked with hooks such as
useEvent
anduseTransition
that allows for the efficient composition of event connections and transitive animations, respectively, without the need to import third party libraries.
The isu
philosophy is to avoid leaking a reference to the underlying Instance wherever possible, instead using pure functions to compose an instance contextually within a component, and relying as much as possible on readily-available library functions instead of data structures to create, access, and store reactive data. This results in a variety of paradigm changes that reduces most operations to simple, self-explanatory function calls instead of operating on classes or objects.
You can obtain the latest version of isu
on the release page. As isu
is unopinionated on how it is loaded, you are free to import it however you like. Normal Roblox procedure is to import it as a ModuleScript. The library returns everything you need to build reactive interfaces. In this example, we've made a simple counter that displays a click count, located inside a LocalScript parented to pre-existing ScreenGui in PlayerGui.
local isu = require(script:WaitForChild('isu'))
local component, useState, useEvent = isu.component, isu.useState, isu.useEvent
local counter = component(function()
local count, setCount = useState(0)
useEvent('MouseButton1Click', function()
setCount(count + 1)
end)
return 'TextButton', {
Size = UDim2.new(0, 200, 0, 200),
Text = 'Clicks: ' .. count
}
end)
counter()().Parent = script.Parent
You can read the in-depth introduction, further examples and the API reference here.
- Functional stateful components powered by contexual coroutines.
- Instance creation/updating with diffing to avoid unnecessary property mutation.
- Essential hooks such as
useState
,useEffect
and mounting/unmounting behavior. - Event composition through
useEvent
to avoid leaking an object reference to the renderer. - Animation composition through
useTransition
to simplify tweening and avoid a notorious Roact problem. - Triggerable animations through
useAnimation
. - Subscription hooks such as
useSubscription
to create stateful derivable values that does not need the renderer to have an effect, such as when the value is used exclusively as an Instance property. - Sequential animations by returning a list of transitions in
useTransition
. - Proper documentation hosted on Github Pages
I initially wrote isu
as a way to fix some of the problems I personally had with Roact and Fusion, as well as to quell my personal disagreement with some of their design choices. Even though I found Fusion to be much closer to what I wanted from a reactive framework, it doesn't use anything contextual for reconciliation and reactivity, instead relying on data structures such as Computed
that are not associated by design to their rendered components. For better or for worse, I opted into designing a library that was far closer to React in usage, and that yielded isu
.