min
06/18/2026, 12:16 PM`staticCompositionLocalOf`: UnlikeI don’t understand this explanation. I know that… •, reads of a `staticCompositionLocalOf`are not tracked by Compose. Changing the value causes the entirety of thecompositionLocalOflambda where thecontentis provided to be recomposed, instead of just the places where the `current`value is read in the Composition.CompositionLocal
CompositionLocal<T> is subclassed by ProvidableCompositionLocal<T>
• Subclasses of ProvidableCompositionLocal<T> are instantiated by the factory functions mentioned above, and override the defaultProvidedValue(value: T): ProvidedValue<T> method.
◦ Instances by compositionLocalOf pass mutationPolicy = this.policy and isDynamic = true to the ProvidedValue<T> constructor.
◦ Instances by staticCompositionLocalOf pass mutationPolicy = null and isDynamic = false to the ProvidedValue<T> constructor.
• .provides(value: T): ProvidedValue<T> calls and returns .defaultProvidedValue(value). The returned ProvidedValue<T> is passed to ProvidableCompositionLocal<T>.valueHolderOf(value: ProvidedValue<T>): ValueHolder<T>.
◦ interface ValueHolder<T> is implemented by DynamicValueHolder<T>, StaticValueHolder<T>, etc.
◦ Instances by compositionLocalOf return a ProvidedValue<T> that’s converted to a DynamicValueHolder<T>(val state: MutableState<T>).
◦ Instances by staticCompositionLocalOf return a ProvidedValue<T> that’s converted to a StaticValueHolder<T>(val value: T).
I also know that the conversion happens when the current Composer starts a provider. So it makes sense that instances by compositionLocalOf would be backed by state objects tracked by the snapshot system.
Changing the value causes the entirety of theBut how can this be true in the case of instances bylambda where thecontentis provided to be recomposedCompositionLocal
staticCompositionLocalOf? They’re not backed by state objects and mutating them wouldn’t invalidate any compositions as a result.Alex Vanyo
06/18/2026, 2:48 PMstaticCompositionLocalOf s are backed by a StaticValueHolder which doesn't have a mutable state, unlike the DynamicValueHolder that backs compositionLocalOf, which does have a mutable state.
I think the best way to think about it is starting from a world that only has static composition locals: if any composition local changes, or if you remove a composition local or provide a new one, then everything needs to recompose. This isn't because a state object changed, it's because something specific to the composition changed.
A "normal" compositionLocalOf is more of a special case: since it is itself backed by mutable state, if that value updates internally, then needing to update "everything" can be skipped since the internally mutable change can be observed directlymin
06/21/2026, 11:47 AMcompositionLocalOf and staticCompositionLocalOf I use makes a difference please? Why is a mutable state even remembered for instances by the first factory? How do you even write to the mutable state?Zach Klippenstein (he/him) [MOD]
06/21/2026, 5:46 PMCompositionLocalProvider (ie the api for mutating a local is the same for both)min
06/22/2026, 12:05 PMmin
06/22/2026, 12:05 PMstaticCompositionLocalOf. When a CompositionLocalProvider is recomposed with a different value for such a local, how does remembering a new StaticValueHolder(value.effectiveValue) for it invalidate the recompose scope of the content composable?