Skip to content

API Reference

A quick map of Flux's public surface, grouped by what you're trying to do. Signatures are simplified for readability; the exhaustive, always-current reference is the strict typing itself, surfaced in your editor by luau-lsp. Click any row to jump to the guide section that teaches it.

T/U denote generic types; Node<T> is a reactive node; ? marks an optional argument. A leading node:/selector:/context:/motion:/async: is a method on that object.

Reactivity

SignatureSummaryGuide
Flux.signal(init: T, equals?) -> Node<T>Create a writable reactive node.Signals
Flux.computed(fn: () -> T, equals?) -> Node<T>Lazily-cached derived node.Computeds
Flux.effect(fn: (prev?) -> ()) -> Node<T>Deferred side-effecting node; re-runs when its deps change.Effects
Flux(obj, effectOrProperty?) -> Node<T>Call shorthand: signal / computed / effect (or bind-from-Instance).Signals
Flux.cleanup(obj)Defer teardown to the current owner: before the enclosing computation re-runs, or on scope destroy.Effects
Flux.untrack(fn?) -> ...Read without tracking deps (or suspend tracking if called bare).Tracking
Flux.retrack()Re-enable tracking after a bare untrack().Tracking
Flux.on(deps, fn, defer?) -> (prev?) -> R?Explicit-dependency reaction; runs fn untracked on change.Tracking
Flux.raw(obj) -> anyRead a node's value without tracking.Tracking
Flux.read(obj) -> anyRead a node's value with tracking (passthrough for non-nodes).Tracking
Flux.listen(node, fn) -> () -> ()Subscribe to updates (Connect-like, own thread); returns an unsubscribe.Effects
Flux.strict(on?) -> booleanToggle/read dev-mode strict graph checks.Strict mode
Flux.isNode(obj) -> booleanTrue if obj is a reactive node.Components
Flux.isReactive() -> booleanTrue when called inside a tracking computed/effect body.Tracking
node:get() -> T · node()Tracked read of a node.Signals
node:peek() -> TUntracked read of a node (current value, no subscribe).Tracking
node:set(value, force?) · node(value)Write a node (force re-fires dependents even when the value is unchanged).Signals
node:update() -> nodeRe-fire dependents without writing (push an in-place table mutation).Signals
node:Destroy() · node:onDestroy(fn)Tear down a node / register a teardown callback.Signals

UI Construction

SignatureSummaryGuide
Flux.new(className) -> (props) -> InstanceCreate an Instance with defaults + reactive props.Creation
Flux.edit(instance) -> (props) -> InstanceHydrate an existing Instance with reactive bindings.Hydration
Flux.model(node) -> TWrap a node for two-way property/attribute binding.Creation
_EVENT = { [signal] = fn }Directive: :Connect handlers & property-change listeners (nested _ATTR for attribute changes).Hydration
_ATTR = { [name] = value | node }Directive: set or bind Roblox attributes.Hydration
_TAG = tag | node | { tag | node }Directive: static or reactive CollectionService tags (diffed: adds new, removes dropped).Hydration
_REF = (instance) -> cleanup? · NodeDirective: receive the built Instance.Hydration
_CLEAN = { Cleanable }Directive: extra teardown tied to Destroying.Hydration
Flux.attr(name, value) · Flux.attr(map)One-off _ATTR for the array portion; repeatable.Hydration
Flux.event(name, fn) · Flux.event(map)One-off _EVENT for the array portion; repeatable.Hydration
Flux.tag(...tags)One-off _TAG for the array portion; repeatable.Hydration
Flux.ref(fn | node)One-off _REF for the array portion.Hydration
Flux.onDestroy(...items)One-off _CLEAN for the array portion; repeatable.Hydration
Flux.DefaultsMutable per-class default props auto-applied by Flux.new (e.g. Frame.BorderSizePixel = 0).Defaults
Flux.Flags.defaultsGlobal on/off for the auto-defaults system (default true; false builds raw instances).Defaults

Lifecycle

SignatureSummaryGuide
Flux.scope(fn) -> (scope, R)Run fn in a fresh owner; nodes, instances, and effects created inside are owned by it.Scopes
scope:Destroy()Tear down a scope and everything it owns.Scopes
Flux.getOwner() -> Node?The owner scope currently evaluating (nil at the root).Scopes
Flux.withOwner(node, fn) -> RRun fn with node as the active owner; new nodes and cleanups attach there.Scopes
Flux.clean(obj: Cleanable)Recursively dispose instances, connections, threads, functions, arrays, immediately.Scopes

Control Flow & Mapping

SignatureSummaryGuide
Flux.show(cond, comp, fallback?) -> NodeMount comp while truthy, fallback when falsy; factories get (value).Conditionals
Flux.showKeyed(cond, comp, fallback?) -> NodeLike show, but remounts on value identity change, not just truthiness.Conditionals
Flux.switch(source) -> (map) -> NodeMount the branch keyed by source's current value; factories get (value).Conditionals
Flux.defaultSentinel key for switch's fallback branch.Conditionals
Flux.forIndex(list, mapFn) -> Node<{U}>Map an array by index; updates item nodes in place.Mapping
Flux.forValue(list, mapFn) -> Node<{U}>Map an array by value (keyed); stable across reorders.Mapping

State

SignatureSummaryGuide
Flux.store(init: T) -> TDeep reactive proxy over a plain table.Stores
Flux.Store.reconcile(proxy, snapshot, key?) -> TDiff a snapshot in; fire only the changed leaves.Stores
Flux.Store.unwrap(proxy) -> TThe raw, un-proxied underlying table.Stores
Flux.Store.insert(proxy, posOrValue, value?)Reactive table.insert for store arrays.Stores
Flux.Store.remove(proxy, pos?) -> anyReactive table.remove for store arrays.Stores
Flux.Store.move(proxy, from, to)Reactive reorder of a store array element.Stores
Flux.Store.destroy(proxy)Tear down a store and its nested proxies.Stores
Flux.selector(source, equals?) -> SelectorO(1) keyed selection (one active key at a time).Selectors
selector:get(key) -> boolean · selector(key)Reactively read whether key is selected.Selectors
selector:destroy()Tear down the selector and its per-key nodes.Selectors
Flux.context(default: T) -> Context<T>Create a dynamically-scoped value.Context
context:get() -> T · context()Read the innermost provided value, else the default.Context
context:provide(value, fn) -> R · context(value, fn)Run fn with the context set to value.Context
Flux.wrap(tbl) -> { [any]: Node }Box a table's plain leaf values into nodes, in place.Wrapping
Flux.async(source, fetcher?, initial?) -> Async<T>Race-guarded fetch (.data/.error/.loading/.state).Async
async:refetch() · async:mutate(v) · async:Destroy()Re-run fetcher / optimistic .data write / tear down.Async
Flux.safe(tryFn, fallback, equals?) -> Node<T>A Computed that falls back to fallback on error.Error Handling
Flux.catch(fn, handler) -> TSynchronous, untracked try / recover.Error Handling

Motion

SignatureSummaryGuide
Flux.spring(target, frequency?, damping?) -> Node<T>Spring toward target (reactive target & params).Spring
Flux.tween(target, info?: TweenInfo) -> Node<T>Tween toward target; info defaults to 0.3 s cubic.Tween
Flux.Motion.step(now?)Advance active motions to clock time now (defaults to os.clock(); auto-called on Heartbeat).Testing
motion:set(value) · motion(value)Retarget the animation goal.Spring
motion:impulse(delta) · motion:setVelocity(v)Add / set velocity (spring only).Spring
motion:Destroy()Tear down the motion and its node.Spring

The Flux.Color toolkit (Color3 in/out, gamut-clipped):

SignatureSummaryGuide
Color.lighten / darken / saturate / desaturate(c, amount) -> Color3Adjust lightness or chroma in Oklab.Manipulation
Color.rotateHue(c, degrees) -> Color3 · Color.grayscale(c) -> Color3Rotate hue (degrees) / strip chroma.Manipulation
Color.mix(a, b, t) -> Color3Perceptual blend in Oklab.Blending
Color.fromTemperature(kelvin) -> Color3Blackbody color for a temperature.Construction
Color.luminance(c) -> number · contrast(a, b) -> number · readable(bg, dark?, light?) -> Color3WCAG luminance / contrast ratio / auto-readable foreground.Accessibility
Color.Oklab.* · Color.sRGB.*Lower-level Oklab (Vector3, hue in degrees) and sRGB↔linear conversions.Oklab

Utilities & Roblox

SignatureSummaryGuide
Flux.padding(value) -> UIPaddingUIPadding from a length, per-side table, or node.Layout
Flux.list(config?) -> UIListLayoutUIListLayout (gap, direction, align, flex semantics).Layout
Flux.grid(config?) -> UIGridLayoutUIGridLayout (cell, gap, fill, align).Layout
Flux.aspectRatio(ratio, type?, axis?) -> UIAspectRatioConstraintAspect-ratio constraint (friendly strings or Enums).Layout
Flux.sizeConstraint(min?, max?) -> UISizeConstraintReactive pixel size bounds.Layout
Flux.flex(mode) -> UIFlexItemUIFlexItem (fill/grow/shrink/none).Layout
Flux.viewport: Node<Vector2>Shared camera viewport-size node.Responsive
Flux.scale: Node<number>UIScale factor derived from the viewport.Responsive
Flux.breakpoint: Node<Breakpoint>Size-class node derived from viewport width.Responsive
Flux.safeArea: Node<Insets>Topbar / GUI inset node (top/bottom/left/right).Responsive
Flux.Responsive.scaleOf(partial?) -> Node<number> · breakpointOf(partial?) -> NodePer-surface scale / breakpoint nodes.Responsive
Flux.Responsive.scaleFor(w, h, partial?) -> number · breakpointFor(w, partial?) -> BreakpointPure scale / breakpoint math (no node).Responsive
Flux.Responsive.configMutable live default responsive config.Responsive
Flux.Find.Child / Descendant / Parent / Query / QueryFirst(query)(props)Instance selectors: apply props to the match(es).Hydration
Flux.Find.Ancestor / AncestorClass / AncestorIsA / ChildClass / ChildIsA(query)(props)Ancestor and class-filtered selectors.Hydration
Flux.flush()Drain the pending-effect queue now (deterministic tests).Testing