As a component tree grows, passing the same value — a theme, a service reference, a locale setting — through every level of props becomes tedious and brittle. Context is Roact’s solution: it lets a component publish a value once, and any descendant can subscribe to it directly, no matter how deep in the tree it sits. Roact’s Context API is modelled on React’s Context API and is the recommended approach for dependency injection, dynamic theming, and scoped state storage.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Roblox/roact/llms.txt
Use this file to discover all available pages before exploring further.
Context was added in Roact 1.3.0. Make sure you are on at least that version before using
Roact.createContext.Creating a Context
CallRoact.createContext(defaultValue) to produce a context object. The defaultValue is returned to any Consumer that has no matching Provider ancestor — it acts as a safe fallback and makes components using the context testable in isolation.
createContext returns a table with exactly two fields: Provider and Consumer. Both are Roact components.
The Consumer Component
ThemeContext.Consumer accepts a single render prop: a function that receives the current context value and returns an element. Roact calls this function whenever the context value changes, so consuming components always have the latest value without any manual wiring.
Provider ancestor exists for ThemeContext, the defaultValue supplied to createContext is passed to render instead.
The Provider Component
ThemeContext.Provider accepts a value prop and any number of children via Roact.Children. Every Consumer that is a descendant of this Provider receives the value. When value changes (i.e. when a parent component calls setState with a new theme), all connected Consumer components automatically re-render with the updated value.
ThemeController wraps its children in the Provider and passes its current state.theme as the context value. Any ThemedButton rendered anywhere inside ThemeController automatically reflects the active theme. Changing self.state.theme (via setState) causes Roact to propagate the new value to all Consumer descendants.
Full Theming Example
Putting it all together:ThemeController near the root of your tree and place ThemedButton anywhere inside it:
Legacy Context (Deprecated)
BeforeRoact.createContext existed, Roact exposed an internal self._context table that components could read and write directly. Unlike the modern API, legacy context values do not update dynamically on their own — you must build your own update mechanism (typically a wrapper component with setState).
Provider side — write to self._context in init:
self._context in init:
createContext API for all new work. It supports dynamic updates, is easier to test, and will continue to be supported as Roact evolves.