Fraxel hooks are functions called inside component functions that provide reactivity, lifecycle management, and access to the scene graph. Like React hooks, they must be called at the top level of a component — but instead of targeting a Virtual DOM, they bind to canvas nodes and their events. Hooks are the primary way to create reactive state, respond to input, manage side effects, and communicate between components in a Fraxel game.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/sanchedev/fraxel/llms.txt
Use this file to discover all available pages before exploring further.
Native Hooks
These hooks are the core primitives provided byfraxel/hooks. All derived hooks are composed from these.
| Hook | Description |
|---|---|
useNode(type) | Creates a typed reference to pass as ref |
useEvent(node, event, callback) | Type-safe event subscription with auto-cleanup on destroy |
useSignal(initial) | Creates reactive state that triggers re-renders |
useComputed(fn) | Creates a derived signal that recomputes when deps change |
useEffect(fn) | Runs effect on mount and when signals change (batched) |
useMount(fn) | Runs once on mount, cleanup on destroy |
useSpawn(node) | Returns a function to dynamically spawn children |
useGame() | Access game controls: play, pause, changeScene |
useChild(path, type) | Gets a reference to a child node by path |
useScript(ref) | Retrieves the FraxelScript attached to a node |
useTrigger(trigger, callback) | Pub/sub for cross-component communication |
createContext(default) | Creates a context with a Provider component |
useContext(context) | Retrieves the current context value |
useRef(value) | Mutable reference that persists across renders |
useNode
useNode(type) creates a NodeReference — a typed, reactive handle to a scene node. Pass it to a JSX element’s ref prop to bind the reference. Once the node mounts, nodeRef.node gives you imperative access to the underlying engine object.
PrimaryNode enum lists every built-in node type:
NodeReference also exposes a .signal getter — a SignalGetter<NodeInstances[T] | null> — so you can reactively track when the node becomes available.
useEvent
useEvent(node, event, callback) subscribes to a named event on a NodeReference. The subscription is automatically removed when the node is destroyed — no manual cleanup needed. The event names are fully type-safe based on the node type passed to useNode.
useEvent auto-cleans up the listener when the node is destroyed. You never need to call .off() manually for events registered this way.useSignal
useSignal(initial) creates a reactive signal. It returns a [getter, setter] tuple. The getter is a callable function — you must call it as health() to read the value, not health directly. Calling the getter inside a useEffect or JSX prop registers it as a dependency.
useComputed
useComputed(fn) creates a derived signal whose value is computed from other signals. It re-runs fn whenever any signal accessed inside it changes, and returns a SignalGetter for the result.
useComputed is purely derived — it has no setter. To update it, update the upstream signal(s) it depends on.
useEffect
useEffect(fn) runs an effect when the node starts, and re-runs it whenever any signal accessed inside fn changes. If fn returns a function, that cleanup is called before each re-run and on node destroy.
Batching
useEffect batches synchronous signal changes — if multiple signals are updated in the same synchronous block, the effect runs once, not once per signal. Re-executions are scheduled via queueMicrotask and run before the next frame.
useMount
useMount(fn) runs a function once when the node’s start() lifecycle fires. It does not re-run on signal changes. If fn returns a cleanup function, that cleanup runs when the node is destroyed.
useMount for one-time setup such as registering subscriptions, starting timers, or calling imperative node methods that require the node to be started first.
useSpawn
useSpawn(node) returns a spawn function that renders a JSX expression and appends the resulting node as a child of the given NodeReference. This is the primary way to dynamically create game objects at runtime.
useGame
useGame() returns GameControls — an object with methods to control global game state: pause, resume, and change scenes.
| Method | Signature | Description |
|---|---|---|
play() | () => void | Resume the game loop |
pause() | () => void | Pause the game loop |
changeScene(name) | (name: string) => Promise<void> | Transition to a named scene |
preloadScene(name) | (name: string) => Promise<void> | Preload a scene without transitioning |
getSize() | () => Vector2 | Returns the canvas dimensions |
createContext / useContext
Fraxel contexts allow you to pass values through the component tree without prop drilling.createContext(defaultValue) creates a context object with a Provider component. useContext(ctx) reads the nearest Provider value above the calling component.
Provider exists above the component, useContext returns the default value passed to createContext.
useTrigger / createTrigger
useTrigger provides a pub/sub pattern for cross-component communication that doesn’t use node events. Create a trigger with createTrigger<T>(), subscribe to it with useTrigger, and fire it with trigger.emit().
useTrigger automatically disconnects the callback when the node is destroyed. Direct use of the Trigger class is also available:
| Method | Description |
|---|---|
trigger.connect(fn) | Subscribe a callback |
trigger.disconnect(fn) | Unsubscribe a callback |
trigger.emit(...args) | Fire all connected callbacks |
useRef
useRef(value) creates a Reference object whose .current property persists across renders and signal updates. Unlike useSignal, mutating .current does not trigger any reactive updates.
useRef for values you need to track across renders (like frame counters, previous values, or imperative handles) that shouldn’t trigger reactive re-computation.
useChild
useChild(path, type) returns a NodeReference to a descendant node located at the given path of id strings. The reference is resolved once after the root node starts.
useChild requires the component to render a single root node. The path is an array of id strings navigating down the tree.
useScript
useScript(ref) returns a SignalGetter containing the FraxelScript instance attached to a given NodeReference. The getter returns undefined until the node and its script have started.
Derived Hooks
Derived hooks are composed from native hooks to provide domain-specific abstractions. They simplify common patterns without introducing unique runtime behavior.| Hook | Description |
|---|---|
useCondition(node, on, off) | Reactive boolean toggled by two opposing events on a node |
useMatch(signal, record) | Maps a signal value to a record (like a switch expression) |
useWhen(signal, trueVal, falseVal) | Ternary computed value based on a boolean signal |
useClickable(ref?) | Clickable node reference with reactive hovered and position state |
useTimer(ref?) | Timer node with reactive time, progress, and controls |
useRayCast(ref?) | RayCast node with reactive detected state and collider |
useCollider(ref?) | Collider node with reactive colliding state and other |
useAnimation(ref?) | AnimationPlayer with reactive frame state and control methods |
useAudio(ref?) | AudioPlayer with reactive playing state and controls |
useCondition
Creates a reactive boolean that flipstrue when on event fires and false when off event fires on the given node:
useClickable
Returns a Clickable node reference, a reactivehovered boolean, and a reactive position signal tracking the pointer’s local coordinates:
ref:NodeReference<PrimaryNode.Clickable>— the node referencehovered:SignalGetter<boolean>—truewhile the pointer is inside the areaposition:SignalGetter<Vector2>— current pointer position in local space, updated every frame while hovering
useTimer
Returns a Timer node reference plus reactivetime and progress signals, and control methods:
time:SignalGetter<number>— current elapsed secondsprogress:SignalGetter<number>—0to1based on durationplay(),pause(),stop()— control methods
useRayCast
Returns a RayCast node reference withdetected and collider reactive signals:
detected:SignalGetter<boolean>—truewhile a collider is hitcollider:SignalGetter<Collider | null>— the currently detected collider
useCollider
Returns a Collider node reference withcolliding and other reactive signals:
colliding:SignalGetter<boolean>—truewhile overlapping another colliderother:SignalGetter<Collider | null>— the other collider in the pair
useAnimation
Returns an AnimationPlayer node reference with reactive animation state and control methods:animName:SignalGetter<string>— current animation nameframeIndex:SignalGetter<number>— current frame indexended:SignalGetter<boolean>—truewhen the animation finishesplay(animName?),setNext(animName?)— control methods
useAudio
Returns an AudioPlayer node reference withplaying state and control methods:
playing:SignalGetter<boolean>—truewhile audio is playingplay(),pause(),stop()— control methods
useMatch
Creates a computed value by mapping a signal’s current value to a record, like aswitch expression:
useWhen
Creates a computed value that switches between two values based on a boolean signal:The List Component
List renders a reactive array of nodes with keyed reconciliation. When the array signal changes, only nodes whose keys are no longer present are destroyed; new keys create fresh nodes; existing keys are untouched.
| Prop | Type | Description |
|---|---|---|
array | T[] | SignalGetter<T[]> | Required. Reactive array to render |
itemKey | (value: T, index: number, arr: T[]) => string | symbol | Required. Unique key extractor |
empty | Fraxel.Node | Fallback node when the array is empty |
children | (value: T, index: number, arr: T[]) => Fraxel.Node | Required. Render function for each item |
Each call to
children must return exactly one root node. Use <transform> or <group> to wrap multiple nodes. List itself renders no wrapper — it uses an internal hidden <transform> as an anchor.Related Pages
Nodes
Every JSX node, its props, events, and methods
Reactivity
Signals, computed values, and reactive prop bindings
Scripts
FraxelScript: attach reusable behavior to nodes
API: Hooks Core
Full TypeScript signatures for all native hooks