---
title: "snapshotFlow"
description: "Create a [Flow] from observable [Snapshot] state. (e.g. state holders returned by
[mutableStateOf][androidx.compose.runtime.mutableStateOf].)

[snapshotFlow] creates a [Flow] that runs [block] when collected and emits the result, recording
any snapshot state that was accessed. While collection continues, if a new [Snapshot] is applied
that changes state accessed by [block], the flow will run [block] again, re-recording the
snapshot state that was accessed. If the result of [block] is not [equal to][Any.equals] the
previous result, the flow will emit that new result. (This behavior is similar to that of
[Flow.distinctUntilChanged][kotlinx.coroutines.flow.distinctUntilChanged].) Collection will
continue indefinitely unless it is explicitly cancelled or limited by the use of other [Flow]
operators.


[block] is run in a **read-only** [Snapshot] and may not modify snapshot data. If [block]
attempts to modify snapshot data, flow collection will fail with [IllegalStateException].

[block] may run more than once for equal sets of inputs or only once after many rapid snapshot
changes; it should be idempotent and free of side effects.

When working with [Snapshot] state it is useful to keep the distinction between **events** and
**state** in mind. [snapshotFlow] models snapshot changes as events, but events **cannot** be
effectively modeled as observable state. Observable state is a lossy compression of the events
that produced that state.

An observable **event** happens at a point in time and is discarded. All registered observers at
the time the event occurred are notified. All individual events in a stream are assumed to be
relevant and may build on one another; repeated equal events have meaning and therefore a
registered observer must observe all events without skipping.

Observable **state** raises change events when the state changes from one value to a new, unequal
value. State change events are **conflated;** only the most recent state matters. Observers of
state changes must therefore be **idempotent;** given the same state value the observer should
produce the same result. It is valid for a state observer to both skip intermediate states as
well as run multiple times for the same state and the result should be the same."
type: "function"
---

<div class='type'>Function</div>


<a id='references'></a>
<div class='sourceset sourceset-common'>Common</div>


```kotlin
public fun <T> snapshotFlow(block: () -> T): Flow<T>
```


Create a `Flow` from observable `Snapshot` state. (e.g. state holders returned by
`mutableStateOf`.)

`snapshotFlow` creates a `Flow` that runs `block` when collected and emits the result, recording
any snapshot state that was accessed. While collection continues, if a new `Snapshot` is applied
that changes state accessed by `block`, the flow will run `block` again, re-recording the
snapshot state that was accessed. If the result of `block` is not `equal to` the
previous result, the flow will emit that new result. (This behavior is similar to that of
`Flow.distinctUntilChanged`.) Collection will
continue indefinitely unless it is explicitly cancelled or limited by the use of other `Flow`
operators.


`block` is run in a **read-only** `Snapshot` and may not modify snapshot data. If `block`
attempts to modify snapshot data, flow collection will fail with `IllegalStateException`.

`block` may run more than once for equal sets of inputs or only once after many rapid snapshot
changes; it should be idempotent and free of side effects.

When working with `Snapshot` state it is useful to keep the distinction between **events** and
**state** in mind. `snapshotFlow` models snapshot changes as events, but events **cannot** be
effectively modeled as observable state. Observable state is a lossy compression of the events
that produced that state.

An observable **event** happens at a point in time and is discarded. All registered observers at
the time the event occurred are notified. All individual events in a stream are assumed to be
relevant and may build on one another; repeated equal events have meaning and therefore a
registered observer must observe all events without skipping.

Observable **state** raises change events when the state changes from one value to a new, unequal
value. State change events are **conflated;** only the most recent state matters. Observers of
state changes must therefore be **idempotent;** given the same state value the observer should
produce the same result. It is valid for a state observer to both skip intermediate states as
well as run multiple times for the same state and the result should be the same.



<div class='sourceset sourceset-common'>Common</div>


```kotlin
@ExperimentalComposeRuntimeApi
public fun <T> snapshotFlow(manager: SnapshotFlowManager, block: () -> T): Flow<T>
```


Create a `Flow` from observable `Snapshot` state. (e.g. state holders returned by
`mutableStateOf`.)

`snapshotFlow` creates a `Flow` that runs `block` when collected and emits the result, recording
any snapshot state that was accessed. While collection continues, if a new `Snapshot` is applied
that changes state accessed by `block`, the flow will run `block` again, re-recording the
snapshot state that was accessed. If the result of `block` is not `equal to` the
previous result, the flow will emit that new result. (This behavior is similar to that of
`Flow.distinctUntilChanged`.) Collection will
continue indefinitely unless it is explicitly cancelled or limited by the use of other `Flow`
operators.

`manager` controls how snapshot state is observed. When the `manager` argument is omitted, a
`SnapshotFlowManager` is instantiated under the hood, so by explicitly managing a
`SnapshotFlowManager` and passing it to multiple `snapshotFlow`s that will be collected on the
same thread, you can improve performance by sharing resources between those `snapshotFlow`s. It
is not safe to share a `SnapshotFlowManager` instance across two `snapshotFlow`s that collect in
parallel on two different threads. Sharing a `SnapshotFlowManager` across `snapshotFlow`s that
cannot be collected in parallel to each other is always encouraged.


`block` is run in a **read-only** `Snapshot` and may not modify snapshot data. If `block`
attempts to modify snapshot data, flow collection will fail with `IllegalStateException`.

`block` may run more than once for equal sets of inputs or only once after many rapid snapshot
changes; it should be idempotent and free of side effects.

When working with `Snapshot` state it is useful to keep the distinction between **events** and
**state** in mind. `snapshotFlow` models snapshot changes as events, but events **cannot** be
effectively modeled as observable state. Observable state is a lossy compression of the events
that produced that state.

An observable **event** happens at a point in time and is discarded. All registered observers at
the time the event occurred are notified. All individual events in a stream are assumed to be
relevant and may build on one another; repeated equal events have meaning and therefore a
registered observer must observe all events without skipping.

Observable **state** raises change events when the state changes from one value to a new, unequal
value. State change events are **conflated;** only the most recent state matters. Observers of
state changes must therefore be **idempotent;** given the same state value the observer should
produce the same result. It is valid for a state observer to both skip intermediate states as
well as run multiple times for the same state and the result should be the same.



## Code Examples
### snapshotFlowSample
```kotlin
@Suppress("UNREACHABLE_CODE", "CanBeVal", "UNUSED_VARIABLE")
fun snapshotFlowSample() {
    // Define Snapshot state objects
    var greeting by mutableStateOf("Hello")
    var person by mutableStateOf("Adam")
    // ...
    // Create a flow that will emit whenever our person-specific greeting changes
    val greetPersonFlow = snapshotFlow { "$greeting, $person" }
    // ...
    val collectionScope: CoroutineScope = TODO("Use your scope here")
    // Collect the flow and offer greetings!
    collectionScope.launch { greetPersonFlow.collect { flowGreeting -> println(flowGreeting) } }
    // ...
    // Change snapshot state; greetPersonFlow will emit a new greeting
    Snapshot.withMutableSnapshot {
        greeting = "Ahoy"
        person = "Sean"
    }
}
```

