Skip to content

Flux ​

Reactive UI library for Roblox and Luau, including fine-grained signals, declarative instances, layout, motion, Flux.Clock, and Flux.Sync.

luau
local count = Flux.signal(0)
Flux.new "TextButton" {
	Parent = gui,
	Text = function() return `Clicked {count()} times` end,
	Activated = function() count(count() + 1) end,
}

Types ​

Node type ​

luau
type Node<T> = Graph.Node<T>

State type ​

luau
type State<T> = Graph.State<T>

Reactive type ​

luau
type Reactive<T> = Graph.Reactive<T>

Unwrap type ​

luau
type Unwrap<T> = Graph.Unwrap<T>

Owner type ​

luau
type Owner = Graph.Owner

Cleanable type ​

luau
type Cleanable = Graph.Cleanable

Props type ​

luau
type Props<ClassName, Extra = {}> = Type.Merge<Type.Properties<Type.Resolve<ClassName>>, Extra>

Child type ​

luau
type Child = Instance | GraphNode | ((instance: Instance) -> ()) | { [any]: any }

Children type ​

luau
type Children = { Child }

Component type ​

luau
type Component<P, I = Instance> = (props: P) -> I

Partial type ​

luau
type Partial<T> = Edit.Partial<T>

Pick type ​

luau
type Pick<T, G> = Edit.Pick<T, G>

Omit type ​

luau
type Omit<T, G> = Edit.Omit<T, G>

Async type ​

luau
type Async<T> = Async.Async<T>

AsyncState type ​

luau
type AsyncState = Async.AsyncState

Context type ​

luau
type Context<T> = Graph.Context<T>

Selector type ​

luau
type Selector<K> = Conditional.Selector<K>

Spring type ​

luau
type Spring<T> = Motion.Spring<T>

SyncSignal type ​

luau
type SyncSignal<T = any> = Sync.SyncSignal<T>

SyncValidator type ​

luau
type SyncValidator<T> = Sync.Validator<T>

HoverOptions type ​

luau
type HoverOptions = Interact.HoverOptions

Breakpoint type ​

luau
type Breakpoint = Responsive.Breakpoint

Input type ​

luau
type Input = Responsive.Input

Platform type ​

luau
type Platform = Responsive.Platform

TextSize type ​

luau
type TextSize = Responsive.TextSize

DisplaySize type ​

luau
type DisplaySize = Responsive.DisplaySize

Length type ​

luau
type Length = Layout.Length

ReactiveLength type ​

luau
type ReactiveLength = Layout.ReactiveLength

Insets type ​

luau
type Insets = Layout.Insets

Align type ​

luau
type Align = Layout.Align

FlexAlign type ​

luau
type FlexAlign = Layout.FlexAlign

LineAlign type ​

luau
type LineAlign = Layout.LineAlign

Direction type ​

luau
type Direction = Layout.Direction

FlexMode type ​

luau
type FlexMode = Layout.FlexMode

PaddingSides type ​

luau
type PaddingSides = Layout.PaddingSides

CornerSides type ​

luau
type CornerSides = Layout.CornerSides

ListConfig type ​

luau
type ListConfig = Layout.ListConfig

GridConfig type ​

luau
type GridConfig = Layout.GridConfig

StrokeConfig type ​

luau
type StrokeConfig = Layout.StrokeConfig

GradientConfig type ​

luau
type GradientConfig = Layout.GradientConfig

SizeConstraintConfig type ​

luau
type SizeConstraintConfig = Layout.SizeConstraintConfig

TextSizeConstraintConfig type ​

luau
type TextSizeConstraintConfig = Layout.TextSizeConstraintConfig

Properties ​

Color from Motion ​

luau
Flux.Color: Color

Perceptual Color3 utilities in Oklab (lighten, saturate, mix, rotateHue, and WCAG contrast/readable).

Open Documentation

Defaults Read Only from Edit ​

luau
Flux.Defaults: { [string]: { [string]: unknown } }

Mutable table of per-class default properties applied by Flux.new.

Open Documentation

Find from Edit ​

luau
Flux.Find: Find

Instance selectors (Child, Descendant, Ancestor, Path, Query) for hydrating trees inside Flux.edit.

Open Documentation

Flags from Edit ​

luau
Flux.Flags: Flags

Global behavior flags (Flags.defaults toggles per-class defaults in Flux.new).

Open Documentation

Sync Module ​

luau
Flux.Sync: Sync

Network-synchronized signals replicated from the server to clients once per frame. Use sig:of(player) for per-player values and pass a validate callback to allow client writes.

Open Documentation

otherwise Read Only from Conditional ​

luau
Flux.otherwise: any

Catch-all branch key for Flux.switch maps when source matches no explicit key.

luau
Flux.switch(state) {
	loading = function() return Spinner {} end,
	[Flux.otherwise] = function(value) return Label { text = value } end,
}

Open Documentation

Functions ​

edit ​

luau
Flux.edit<T>(instance: T & Instance)

Applies reactive properties, events, children, and directives to an existing Instance. Bindings created inside a Flux.scope disconnect when the scope is destroyed.

luau
Flux.edit(existingLabel) { Text = function() return `HP {health()}` end }

Open Documentation

new ​

luau
Flux.new<T>(className: T | keyof<Type.Creatable>)

Creates a Roblox Instance of className with its per-class defaults and applies a table of properties, events, children, and directives. When called inside a Flux.scope, the instance is destroyed with the scope.

luau
Flux.new "Frame" {
	Size = UDim2.fromScale(1, 1),
	BackgroundTransparency = function() return if hovered() then 0 else 0.5 end,
	_attr_Kind = "Panel",
	_tag_Interactive = true,
	Flux.new "UICorner" {},
}

Open Documentation

signal from Graph ​

luau
Flux.signal(initial: any, equals: any): any

Creates a writable signal holding initial, using equals (default ==) to skip unchanged writes. Signals aren't owned by enclosing scopes and are garbage-collected once unreferenced.

luau
local count = Flux.signal(0)
count(count() + 1)

Open Documentation

computed from Graph ​

luau
Flux.computed(fn: any, equals: any): any

Creates a lazily cached computed node derived from fn. Re-evaluates only when read after a dependency changes, and uses equals (default ==) to stop propagation when the result is unchanged.

luau
local total = Flux.computed(function()
	return price() * quantity()
end)

Open Documentation

effect from Graph ​

luau
Flux.effect(fn: (...any) -> ...any): any

Schedules fn to run on the next flush and re-run whenever any node it reads changes. Owned by the enclosing scope or stopped manually with node:Destroy().

luau
Flux.effect(function() print("count is", count()) end)

Open Documentation

createSignal from Graph ​

luau
Flux.createSignal<T>(initial: T, equals: ((T, T: any) -> boolean)?): (() -> T, (value: T, force: boolean?) -> T)

Creates a lightweight signal without a node wrapper and returns (getter, setter). Faster and smaller than Flux.signal, with no methods (Destroy, onObserved, etc.).

luau
local count, setCount = Flux.createSignal(0)
Flux.effect(function()
	print(count())
end)
setCount(count() + 1)

createMemo from Graph ​

luau
Flux.createMemo<T>(fn: () -> T, equals: ((T, T) -> boolean)?): () -> T

Creates a lightweight computed without a node wrapper and returns its tracked getter function. Owned by the active scope or reaction like Flux.computed.

luau
local count, setCount = Flux.createSignal(1)
local doubled = Flux.createMemo(function()
	return count() * 2
end)

createEffect from Graph ​

luau
Flux.createEffect(fn: (...any) -> ...any)

Creates a lightweight effect without returning a node wrapper. Owned by the active scope or reaction like Flux.effect.

luau
local count, setCount = Flux.createSignal(0)
Flux.createEffect(function()
	print("count is", count())
end)

getter from Graph ​

luau
Flux.getter(node: any): any

Returns a plain function that reads node with tracking, avoiding wrapper __call overhead in hot loops.

luau
local count = Flux.signal(0)
local getCount = Flux.getter(count)
Flux.effect(function()
	print(getCount())
end)

setter from Graph ​

luau
Flux.setter(node: any): any

Returns a plain function that writes node (setter(value, force)), avoiding wrapper __call overhead in hot loops.

scope from Graph ​

luau
Flux.scope<T>(fn: (scope: Node<any>) -> T): (Node<any>, T)

Runs fn in a new owner scope and returns (scope, result). Calling scope:Destroy() tears down every computed, effect, instance, and cleanup created inside fn.

luau
local scope, frame = Flux.scope(function() return Flux.new "Frame" { Parent = gui } end)
scope:Destroy() -- destroys the frame and everything bound to it

Open Documentation

flush from Graph ​

luau
Flux.flush()

Runs all queued effects immediately instead of waiting for the next frame.

Open Documentation

cleanup from Graph ​

luau
Flux.cleanup(obj: Cleanable)

Registers obj to be disposed via Flux.dispose before the running reaction re-runs and when its owner is destroyed. Cleanup functions receive (previousValue, isDestroyed).

luau
Flux.effect(function()
	local connection = button.Activated:Connect(onClick)
	Flux.cleanup(connection)
end)

Open Documentation

dispose from Graph ​

luau
Flux.dispose(obj: Cleanable?)

Tears down obj immediately (functions, instances, connections, threads, objects with Destroy/Disconnect methods, or arrays of cleanables). Runs untracked and warns on error instead of throwing.

luau
local connections = { part.Touched:Connect(onTouched), part.Destroying:Connect(onGone) }
Flux.dispose(connections)

Open Documentation

getOwner from Graph ​

luau
Flux.getOwner(): Owner?

Returns the active reactive owner, or nil at the root. Pass it to Flux.withOwner to attach deferred work to the same scope.

Open Documentation

withOwner from Graph ​

luau
Flux.withOwner(node: any, fn: () -> ...any): ...any

Runs fn with owner (from Flux.getOwner, a node, or nil for unowned roots) as the active owner and restores its captured context. If owner is already destroyed, anything created inside fn is disposed as soon as fn finishes.

Open Documentation

read from Graph ​

luau
Flux.read(object: any): any

Reads a Reactive value (node, getter function, or plain value) and subscribes the running reaction if it's dynamic.

luau
local function Label(props: { text: Flux.Reactive<string> })
	return Flux.new "TextLabel" { Text = function() return string.upper(Flux.read(props.text)) end }
end

Open Documentation

raw from Graph ​

luau
Flux.raw(object: any): any

Reads a Reactive value (node, getter function, or plain value) without subscribing the running reaction.

Open Documentation

untrack from Graph ​

luau
Flux.untrack(fn: (() -> ...any)?): ...any

Runs fn without dependency tracking and returns its result. Called with no arguments (Flux.untrack()), it suspends tracking for the rest of the current reaction body or until Flux.retrack().

luau
Flux.effect(function()
	local id = selected() -- tracked
	local name = Flux.untrack(function() return names()[id] end) -- not tracked
end)

Open Documentation

retrack from Graph ​

luau
Flux.retrack()

Resumes tracking after a bare Flux.untrack() in the same function body.

luau
Flux.untrack()
local snapshot = rows()
Flux.retrack()

Open Documentation

isNode from Graph ​

luau
Flux.isNode(object: any): boolean

Returns true if object is a Flux node.

Open Documentation

isReactive from Graph ​

luau
Flux.isReactive(): boolean

Returns true if called inside a tracking computed or effect.

on from Bind ​

luau
Flux.on<D, R>(deps: any, fn: (input: any, prevInput: any?, prevResult: R?) -> R, defer: boolean?): (prevResult: R?) -> R?

Wraps fn so a computed or effect tracks only deps and runs fn(input, prevInput, prevResult) untracked. Pass defer = true to skip the initial run and fire only when deps change.

Open Documentation

listen from Bind ​

luau
Flux.listen<T>(node: Graph.Node<T>, fn: (value: T) -> ()): () -> ()

Subscribes fn to updates of node with RBXScriptSignal:Connect semantics and returns an unsubscribe function. Fires on each flush after node changes, spawning fn(value) on its own thread via task.spawn so callbacks may yield freely.

Open Documentation

context from Graph ​

luau
Flux.context(default: any): any

Creates a context with the given default value for passing data down a component tree without prop drilling.

luau
local Theme = Flux.context("dark")
Theme:provide("light", function() return App {} end) -- App and everything it builds reads "light"

Open Documentation

bindContext from Graph ​

luau
Flux.bindContext<A..., R...>(fn: (A...) -> R...): (A...) -> R...

Wraps fn so every call sees the context values active when bindContext was called. Event handlers in Flux.new/Flux.edit do this automatically.

luau
local onClick = Flux.bindContext(function()
	print(ThemeContext:get()) -- the value provided where onClick was made
end)

Open Documentation

async from Async ​

luau
Flux.async(source: any, fetcher: any, initialValue: any): Async<any>

Runs yielding work off the reactive graph and exposes its progress as .data, .error, .loading, and .state nodes. fetcher(value, previous, refetching) runs untracked whenever source is truthy, and stale in-flight results are discarded automatically.

luau
local profile = Flux.async(userId, function(id) return Players:GetNameFromUserIdAsync(id) end)
Flux.new "TextLabel" { Text = function() return profile.data() or "Loading" end }

Open Documentation

selector from Conditional ​

luau
Flux.selector<S, K>(source: S, equals: ((sourceValue: Graph.Unwrap<S>, key: K) -> boolean)?): Selector<K>

Creates a keyed selector that tracks which key matches source in O(1) (or O(observed keys) with a custom equals comparator).

Open Documentation

store from Store ​

luau
Flux.store<T>(initialState: T): T

Wraps a plain table in a deep reactive proxy that tracks each read key, nested table, and array length independently. Values that already have a metatable (such as Flux nodes or class instances) are left untouched.

Open Documentation

split from Edit ​

luau
Flux.split(props: any, keys: any, ...: any): ...any

Partitions props into one table per keys group plus a final table holding every remaining key, leaving props untouched. Pass a schema table or an annotated key-literal array ({ "label" | "onClick" }) to preserve exact Pick/Omit types on a single group.

luau
local OWN: { "label" | "onClick" } = { "label", "onClick" }
local own, rest = Flux.split(props, OWN)

Open Documentation

safe from Graph ​

luau
Flux.safe<T>(tryFn: () -> T, fallback: T | (err: unknown) -> T, equals: ((a: T, b: T) -> boolean)?): Node<T>

Creates a computed that evaluates tryFn and returns fallback (a static value or an untracked (err) -> T function) if tryFn throws. Automatically recovers when tracked dependencies change.

Open Documentation

property from Bind ​

luau
Flux.property<I, K>(instance: I & Instance, property: K | "Name"): Graph.Node<Type.PropertyType<I, K>>

Creates a node mirroring an Instance property, an attribute ($Name or _attr_Name), or a CollectionService tag (#Tag or _tag_Tag). Disconnects automatically when the node or its owning scope is destroyed.

luau
local text = Flux.property(textBox, "Text")
local health = Flux.property(character, "$Health")
local isEnemy = Flux.property(character, "#Enemy")

Open Documentation

model from Bind ​

luau
Flux.model<N>(node: N): Graph.Unwrap<N>

Wraps a reactive node for two-way binding on an Instance property, attribute, or tag. Updates the instance from node and writes changes back to node when the instance fires its changed signal.

Open Documentation

isModel from Bind ​

luau
Flux.isModel(value: unknown): boolean

Returns true when value is a Flux.model wrapper.

Open Documentation

modelNode from Bind ​

luau
Flux.modelNode(value: unknown): Graph.Node<any>?

Returns the underlying node from a Flux.model wrapper, or nil if value is not a model.

luau
local node = Flux.modelNode(props.value)
if node then
	node:set(text)
end

Open Documentation

show from Conditional ​

luau
Flux.show<T, F>(condition: unknown, component: (value: () -> any) -> T, fallback: ((value: () -> any) -> F)?): Node<T | F>

Mounts component while condition is truthy, or fallback when falsy, in its own child scope. Rebuilds only when truthiness flips (use Flux.showKeyed to rebuild on every identity change).

Open Documentation

showKeyed from Conditional ​

luau
Flux.showKeyed<T, F>(condition: unknown, component: (value: () -> any) -> T, fallback: ((value: () -> any) -> F)?): Node<T | F>

Mounts component while condition is truthy (or fallback when falsy) and remounts in a fresh scope whenever condition changes identity.

Open Documentation

switch from Conditional ​

luau
Flux.switch<S>(source: S)

Mounts the branch factory matching source's current value in its own child scope. Use [Flux.otherwise] in map as a catch-all branch for unmatched values.

Open Documentation

presence from Conditional ​

luau
Flux.presence<T>(condition: unknown, component: (exiting: Node<boolean>, done: () -> ()) -> T): Node<T?>

Mounts component(exiting, done) while condition is truthy and keeps it mounted while exiting() is true until done() is called. If condition turns truthy again before done() runs, exiting flips back to false without remounting.

Open Documentation

pick from Conditional ​

luau
Flux.pick(condition: unknown, whenTrue: any, whenFalse: any?): Node<any>

Derives a node returning whenTrue while condition is truthy and whenFalse otherwise. Only the active branch is read, and no branch scope is created.

Open Documentation

fallback from Conditional ​

luau
Flux.fallback<V, D>(value: V, default: D): Node<NonNil<Graph.Unwrap<V>> | Graph.Unwrap<D>>

Derives a node returning value when non-nil, or default when value is nil. Preserves false instead of replacing it like or.

Open Documentation

forValue from Conditional ​

luau
Flux.forValue<L, U>(list: L, mapFn: (index: Node<number>, value: Item<L>) -> U): Node<{ U }>

Maps list by item identity, running mapFn(index, value) once per unique value and updating index when an item moves. Values must be unique (use Flux.forIndex for primitive or duplicate values).

Open Documentation

forIndex from Conditional ​

luau
Flux.forIndex<L, U>(list: L, mapFn: (index: number, item: Node<Item<L>>) -> U): Node<{ U }>

Maps list by numeric index, running mapFn(index, item) once per slot and updating item in place when the value at that index changes.

Open Documentation

spring from Motion ​

luau
Flux.spring<A>(target: A, frequency: Reactive<number>?, damping: Reactive<number>?, initialVelocity: any?): Spring<Unwrap<A>>

Creates a node that animates toward target using an analytic harmonic oscillator (frequency in Hz and damping ratio both default to 1 and may be reactive). Retargets preserve current velocity.

luau
local size = Flux.spring(function() return if open() then 300 else 0 end, 4)

Open Documentation

tween from Motion ​

luau
Flux.tween<A>(target: A, tweenInfo: Reactive<TweenInfo>?): Graph.Node<Unwrap<A>>

Creates a node that eases toward target over a TweenInfo curve. When target or tweenInfo changes, the tween restarts from its current value without waiting for DelayTime.

Open Documentation

padding from Layout ​

luau
Flux.padding(value: Length | PaddingSides | Graph.Node<any> | (() -> Length | Insets)): UIPadding

Creates a UIPadding from a single length, a { top, bottom, left, right, x, y } table, or a reactive source. Plain number values are interpreted as offset pixels.

Open Documentation

corner from Layout ​

luau
Flux.corner(radius: ReactiveLength | CornerSides?): UICorner

Creates a UICorner from an offset pixel radius, a UDim, or a per-corner { topLeft, topRight, bottomLeft, bottomRight, top, bottom, left, right, radius } table.

Open Documentation

stroke from Layout ​

luau
Flux.stroke(config: StrokeConfig?): UIStroke

Creates a UIStroke with static or reactive thickness, color, transparency, mode, joins, position, and offset.

Open Documentation

aspectRatio from Layout ​

luau
Flux.aspectRatio(ratio: Reactive<number>, aspectType: Reactive<"fit" | "scale" | Enum.AspectType>?, dominantAxis: Reactive<"width" | "height" | Enum.DominantAxis>?): UIAspectRatioConstraint

Creates a UIAspectRatioConstraint with ratio, aspectType ("fit" or "scale"), and dominantAxis ("width" or "height").

Open Documentation

list from Layout ​

luau
Flux.list(config: ListConfig?): UIListLayout

Creates a UIListLayout with SortOrder = LayoutOrder and flexbox-style gap, direction, align (cross-axis), justify (main-axis), and wraps options.

Open Documentation

grid from Layout ​

luau
Flux.grid(config: GridConfig?): UIGridLayout

Creates a UIGridLayout with SortOrder = LayoutOrder and cell, gap, fill, align, justify, and maxCells options.

Open Documentation

flex from Layout ​

luau
Flux.flex(mode: Reactive<FlexMode | Enum.UIFlexMode>?): UIFlexItem

Creates a UIFlexItem with mode ("fill" by default, "grow", "shrink", or "none").

Open Documentation

gradient from Layout ​

luau
Flux.gradient(config: GradientConfig?): UIGradient

Creates a UIGradient from single values, evenly spaced stop arrays, or sequences for color and transparency.

Open Documentation

sizeConstraint from Layout ​

luau
Flux.sizeConstraint(config: SizeConstraintConfig?): UISizeConstraint

Creates a UISizeConstraint from min/max Vector2 bounds or per-axis minWidth, minHeight, maxWidth, and maxHeight bounds.

Open Documentation

textSizeConstraint from Layout ​

luau
Flux.textSizeConstraint(config: TextSizeConstraintConfig?): UITextSizeConstraint

Creates a UITextSizeConstraint bounding text size between min and max pixels.

Open Documentation

Metamethods ​

__call ​

luau
Flux.__call(_: any, obj: any, propertyName: string?): Graph.Node<any>

Terse untyped constructor for a signal (Flux(value)), computed (Flux(fn)), or instance property node (Flux(instance, key)). Use Flux.signal, Flux.computed, and Flux.property when you want strict type inference.

luau
local size = Flux(frame, "AbsoluteSize")

Open Documentation

Clock ​

Shared time source for timers, frame callbacks, and deterministic test stepping. Call Clock.manual(true) and Clock.step(seconds) in tests to advance timers, motion, and frame flushes in order.

Open Documentation

now from Clock ​

luau
Flux.Clock.now(): number

Seconds on a monotonic clock, for measuring intervals: os.clock() in a game, virtual time on a manual clock.

wall from Clock ​

luau
Flux.Clock.wall(): number

Unix time in seconds, for dates and countdowns shared between players: workspace:GetServerTimeNow() in a game, 2026-01-01T00:00:00Z + now() on a manual clock.

delay from Clock ​

luau
Flux.Clock.delay<A...>(seconds: number?, fn: ((A...) -> ...any) | thread, ...: A...): thread

Runs fn(...) (or resumes a thread) after seconds, like task.delay. Returns the thread, for cancel.

wait Yields from Clock ​

luau
Flux.Clock.wait(seconds: number?): number

Yields the running thread for seconds (default: one frame), like task.wait, and returns the time it waited. On a manual clock it waits for a step to pass the deadline, so it needs a coroutine to yield.

defer from Clock ​

luau
Flux.Clock.defer<A...>(fn: ((A...) -> ...any) | thread, ...: A...): thread

Runs fn(...) (or resumes a thread) once the current work finishes, like task.defer. On a manual clock it waits for drain() (which every step frame calls). Returns the thread, for cancel.

cancel from Clock ​

luau
Flux.Clock.cancel(thread: thread)

Cancels a thread from delay, defer or a wait, like task.cancel.

connect from Clock ​

luau
Flux.Clock.connect(phase: Phase, fn: (dt: number) -> ()): () -> ()

Calls fn(dt) every frame at phase ("PreRender", "RenderStepped" or "Heartbeat"). Returns a function that disconnects it. A manual clock calls it from step instead of the engine's frames.

manual from Clock ​

luau
Flux.Clock.manual(on: boolean)

Toggles manual clock mode for tests (headless Luau is always manual). Disabling manual mode clears pending tasks via Clock.reset().

isManual from Clock ​

luau
Flux.Clock.isManual(): boolean

Tests only: whether the clock is manual.

step from Clock ​

luau
Flux.Clock.step(seconds: number, frameLength: number?)

Tests only: advances a manual clock by seconds, in frames of at most frameLength seconds (default 1/60). step(0) runs one frame of zero length: due timers, subscribers, a Flux step and the deferred work.

drain from Clock ​

luau
Flux.Clock.drain()

Tests only: runs deferred work until none is left, including work it defers in turn. Errors after 10000 calls, when deferred work keeps deferring more.

reset from Clock ​

luau
Flux.Clock.reset()

Tests only: drops every pending timer, wait, deferred call and manual subscriber. now keeps its value.

Interact ​

Read-only interaction state nodes (hover, press, selected, focused) and pointer hit-testing helpers (pointIn, sunk, covered).

Open Documentation

pointIn from Interact ​

luau
Flux.Interact.pointIn(x: number, y: number, object: GuiObject): boolean

Whether the point (x, y) lies within object's absolute bounds (inclusive, ignoring rotation). Coordinates are inset-relative, matching InputObject.Position and AbsolutePosition.

Open Documentation

sunk from Interact ​

luau
Flux.Interact.sunk(x: number, y: number, object: GuiObject, token: any?): boolean

Returns true when input at (x, y) would be claimed by an Active or input-sinking GUI rendered above object (or while the Roblox escape menu is open). Pass the InputObject as token to share the hit-test query across multiple controls on the same input event.

Open Documentation

covered from Interact ​

luau
Flux.Interact.covered(x: number, y: number, object: GuiObject, token: any?): boolean

Returns true when input at (x, y) would be claimed by an Active or input-sinking GUI above object that is not a descendant of object.

Open Documentation

hover from Interact ​

luau
Flux.Interact.hover(object: GuiObject, options: HoverOptions?): Graph.Node<boolean>

Returns a read-only boolean node that is true while a pointer or touch contact is inside object with no input-claiming GUI above it. Pass { within = true } on containers so child controls inside object do not count as covering it.

Open Documentation

press from Interact ​

luau
Flux.Interact.press(object: GuiObject): Graph.Node<boolean>

Returns a read-only boolean node that is true while object is held down by pointer, touch, or gamepad/keyboard activation (ButtonA/Enter). Stays true until that input ends anywhere on screen.

Open Documentation

selected from Interact ​

luau
Flux.Interact.selected(object: GuiObject): Graph.Node<boolean>

Returns a read-only boolean node tracking whether object is currently GuiService.SelectedObject.

Open Documentation

focused from Interact ​

luau
Flux.Interact.focused(textBox: TextBox): Graph.Node<boolean>

Returns a read-only boolean node tracking whether textBox currently has keyboard focus.

Open Documentation

Motion ​

Advances active Flux.spring and Flux.tween nodes. Stepped automatically each frame, or manually in tests via Motion.step(dt).

Open Documentation

step from Motion ​

luau
Flux.Motion.step(dt: number?)

Advances every active spring and tween by dt seconds (or the time since the last step). Wired to RunService automatically in Roblox, so you only call this in tests (Flux.Motion.step(1 / 60)).

Open Documentation

Responsive ​

Reactive nodes for viewport size, UI scale, breakpoints, device platform, active input mode, and accessibility settings.

Open Documentation

config Read Only from Responsive ​

luau
Flux.Responsive.config: Config

Default responsive configuration shared by derived nodes. Mutate once at startup before building UI.

Open Documentation

platform Read Only from Responsive ​

luau
Flux.Responsive.platform: Graph.Node<Platform>

Active device class ("vr", "console", "pc", or "mobile"), updated live on the client ("pc" off-client).

Open Documentation

viewport Read Only from Responsive ​

luau
Flux.Responsive.viewport: Graph.Node<Vector2>

The active camera's ViewportSize as a node, live on the client.

Open Documentation

scale Read Only from Responsive ​

luau
Flux.Responsive.scale: Graph.Node<number>

UI scale factor derived from viewport (1.0 at config.reference).

Open Documentation

breakpoint Read Only from Responsive ​

luau
Flux.Responsive.breakpoint: Graph.Node<Breakpoint>

Size class ("phone" | "tablet" | "desktop") derived from viewport width.

Open Documentation

displaySize Read Only from Responsive ​

luau
Flux.Responsive.displaySize: Graph.Node<DisplaySize>

Physical screen size class ("Small", "Medium", or "Large") mirroring GuiService.ViewportDisplaySize.

Open Documentation

input Read Only from Responsive ​

luau
Flux.Responsive.input: Graph.Node<Input>

Active input mode ("keyboard", "touch", or "gamepad") tracking UserInputService.PreferredInput on the client.

Open Documentation

textSize Read Only from Responsive ​

luau
Flux.Responsive.textSize: Graph.Node<TextSize>

Player's preferred text size ("Medium", "Large", "Larger", or "Largest") from GuiService.PreferredTextSize. Roblox scales rendered text automatically, so use this to adjust surrounding container spacing rather than multiplying TextSize.

Open Documentation

reducedMotion Read Only from Responsive ​

luau
Flux.Responsive.reducedMotion: Graph.Node<boolean>

Tracks GuiService.ReducedMotionEnabled (true when the player prefers reduced motion).

Open Documentation

preferredTransparency Read Only from Responsive ​

luau
Flux.Responsive.preferredTransparency: Graph.Node<number>

Tracks GuiService.PreferredTransparency from 0 (opaque backgrounds) to 1 (default).

Open Documentation

scaleOf from Responsive ​

luau
Flux.Responsive.scaleOf(partial: PartialConfig?): Graph.Node<number>

Factory escape hatch: a scale node with per-surface config (merged over defaults).

Open Documentation

breakpointOf from Responsive ​

luau
Flux.Responsive.breakpointOf(partial: PartialConfig?): Graph.Node<Breakpoint>

Factory escape hatch: a breakpoint node with per-surface thresholds.

Open Documentation

Store ​

Array mutation (insert, remove, move), snapshot diffing (reconcile), unwrapping (unwrap), and teardown (Destroy) for Flux.store proxies.

Open Documentation

insert from Store ​

luau
Flux.Store.insert(proxy: any, posOrValue: any, value: any?)

Inserts value into a store array (appending with 2 arguments, or inserting at posOrValue with 3) and notifies length and index observers.

Open Documentation

remove from Store ​

luau
Flux.Store.remove(proxy: any, pos: number?): any

Removes and returns the element at pos (defaulting to the last element) from a store array and notifies length and index observers.

Open Documentation

move from Store ​

luau
Flux.Store.move(proxy: any, from: number, to: number)

Moves the element at 1-based index from to to in a single tracked step without tearing down nested item proxies.

Open Documentation

reconcile from Store ​

luau
Flux.Store.reconcile<T>(proxy: T, newData: T, key: string?): T

Diffs newData into the store proxy in place, firing only changed leaf nodes and reusing unchanged nested proxies. Pass key to match array elements by element[key] instead of array index.

Open Documentation

unwrap from Store ​

luau
Flux.Store.unwrap<T>(proxy: T): T

Returns the raw, unproxied backing table of a store for untracked reads or serialization.

Open Documentation

Destroy from Store ​

luau
Flux.Store.Destroy<T>(proxy: T)

Tears down a store and all of its nested proxies, disposing their per-key nodes via Flux.dispose while leaving the raw backing table intact.

Open Documentation