# Applier

Artifact: [androidx.compose.runtime:runtime](https://developer.android.com/jetpack/androidx/releases/compose-runtime) [View Source](https://cs.android.com/search?q=file:androidx/compose/runtime/Applier.kt+class:androidx.compose.runtime.Applier) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0) Common/AllAndroid/JVMNative/C/iOSJavaScript
- Cmn

  ```
  interface Applier<N : Any?>
  ```
Known direct subclasses [AbstractApplier](https://developer.android.com/reference/kotlin/androidx/compose/runtime/AbstractApplier)

|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/AbstractApplier` | An abstract `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier` implementation. |

Known indirect subclasses [VectorApplier](https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/vector/VectorApplier)

|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/vector/VectorApplier` |   |

*** ** * ** ***

An Applier is responsible for applying the tree-based operations that get emitted during a composition. Every `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composer` has an `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier` which it uses to emit a `https://developer.android.com/reference/kotlin/androidx/compose/runtime/ComposeNode.composable#ComposeNode(kotlin.Function0,kotlin.Function1)`.

A custom `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier` implementation will be needed in order to utilize Compose to build and maintain a tree of a novel type.

```kotlin
import androidx.compose.runtime.AbstractApplier
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.CompositionContext
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(parent: CompositionContext, content: @Composable () -> Unit): Composition {
    return Composition(NodeApplier(this), parent).apply { setContent(content) }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable
fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable
fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
```

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/AbstractApplier` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composition` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composer` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/runtime/ComposeNode.composable#ComposeNode(kotlin.Function0,kotlin.Function1)` |   |

## Summary

| ### Public functions |
|---|---|---|
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#apply(kotlin.Function2,kotlin.Any)(block: N.(https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html, value: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?)` Apply a change to the current node. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#clear()()` Move to the root and remove all nodes from the root, preparing both this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier` and its root to be used as the target of a new composition in the future. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#down(kotlin.Any)(node: N)` Indicates that the applier is getting traversed "down" the tree. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)(index: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, instance: N)` Indicates that `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)` should be inserted as a child of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` at `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)`. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)(index: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, instance: N)` Indicates that `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` should be inserted as a child to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` at `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)`. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)(from: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, to: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, count: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Indicates that `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` children of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` should be moved from index `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` to index `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)`. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/annotation/EmptySuper https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#onBeginChanges()()` Called when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composer` is about to begin applying changes using this applier. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://developer.android.com/reference/kotlin/androidx/annotation/EmptySuper https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#onEndChanges()()` Called when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composer` is finished applying changes using this applier. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)(index: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html, count: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Indicates that the children of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` from `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)` to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)` + `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)` should be removed. | Cmn |
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#reuse()()` Notify `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` is is being reused in reusable content. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#up()()` Indicates that the applier is getting traversed "up" the tree. | Cmn |

| ### Public properties |
|---|---|---|
| `N` | `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` The node that operations will be applied on at any given time. | Cmn |

## Public functions

### apply

Cmn Added in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.8.0)

```
open fun apply(block: N.(Any?) -> Unit, value: Any?): Unit
```

Apply a change to the current node.

### clear

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun clear(): Unit
```

Move to the root and remove all nodes from the root, preparing both this `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier` and its root to be used as the target of a new composition in the future.

### down

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun down(node: N): Unit
```

Indicates that the applier is getting traversed "down" the tree. When this gets called, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#down(kotlin.Any)` is expected to be a child of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()`, and after this operation, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#down(kotlin.Any)` is expected to be the new `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()`.

### insertBottomUp

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun insertBottomUp(index: Int, instance: N): Unit
```

Indicates that `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)` should be inserted as a child of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` at `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)`. An applier should insert the node into the tree either in `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)`, not both. See the description of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` to which describes when to implement `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` and when to use `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)`.

### insertTopDown

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun insertTopDown(index: Int, instance: N): Unit
```

Indicates that `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` should be inserted as a child to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` at `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)`. An applier should insert the node into the tree either in `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` or `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)`, not both.

The `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` method is called before the children of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` have been created and inserted into it. `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)` is called after all children have been created and inserted.

Some trees are faster to build top-down, in which case the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)` method should be used to insert the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertTopDown(kotlin.Int,kotlin.Any)`. Other trees are faster to build bottom-up in which case `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#insertBottomUp(kotlin.Int,kotlin.Any)` should be used.

To give example of building a tree top-down vs. bottom-up consider the following tree,

```kotlin
      R
      |
      B
     / \
    A   C
```

where the node `B` is being inserted into the tree at `R`. Top-down building of the tree first inserts `B` into `R`, then inserts `A` into `B` followed by inserting `C` into B\`. For example,

```kotlin
    1           2           3
    R           R           R
    |           |           |
    B           B           B
               /           / \
              A           A   C
```

A bottom-up building of the tree starts with inserting `A` and `C` into `B` then inserts `B` tree into `R`.

```kotlin
    1           2           3
    B           B           R
    |          / \          |
    A         A   C         B
                           / \
                          A   C
```

To see how building top-down vs. bottom-up can differ significantly in performance consider a tree where whenever a child is added to the tree all parent nodes, up to the root, are notified of the new child entering the tree. If the tree is built top-down,

1. `R` is notified of `B` entering.

2. `B` is notified of `A` entering, `R` is notified of `A` entering.

3. `B` is notified of `C` entering, `R` is notified of `C` entering.

for a total of 5 notifications. The number of notifications grows exponentially with the number of inserts.

For bottom-up, the notifications are,

1. `B` is notified `A` entering.

2. `B` is notified `C` entering.

3. `R` is notified `B` entering.

The notifications are linear to the number of nodes inserted.

If, on the other hand, all children are notified when the parent enters a tree, then the notifications are, for top-down,

1. `B` is notified it is entering `R`.

2. `A` is notified it is entering `B`.

3. `C` is notified it is entering `B`.

which is linear to the number of nodes inserted.

For bottom-up, the notifications look like,

1. `A` is notified it is entering `B`.

2. `C` is notified it is entering `B`.

3. `B` is notified it is entering `R`, `A` is notified it is entering `R`, `C` is notified it is entering `R`.

   which exponential to the number of nodes inserted.

### move

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun move(from: Int, to: Int, count: Int): Unit
```

Indicates that `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` children of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` should be moved from index `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` to index `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)`.

The `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` index is relative to the position before the change, so, for example, to move an element at position 1 to after the element at position 2, `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` should be `1` and `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#move(kotlin.Int,kotlin.Int,kotlin.Int)` should be `3`. If the elements were A B C D E, calling `move(1, 3, 1)` would result in the elements being reordered to A C B D E.

### onBeginChanges

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
@EmptySuper
open fun onBeginChanges(): Unit
```

Called when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composer` is about to begin applying changes using this applier. `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#onEndChanges()` will be called when changes are complete.

### onEndChanges

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
@EmptySuper
open fun onEndChanges(): Unit
```

Called when the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composer` is finished applying changes using this applier. A call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#onBeginChanges()` will always precede a call to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#onEndChanges()`.

### remove

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun remove(index: Int, count: Int): Unit
```

Indicates that the children of `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` from `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)` to `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)` + `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#remove(kotlin.Int,kotlin.Int)` should be removed.

### reuse

Cmn Added in [1.8.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.8.0)

```
open fun reuse(): Unit
```

Notify `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` is is being reused in reusable content.

### up

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
fun up(): Unit
```

Indicates that the applier is getting traversed "up" the tree. After this operation completes, the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` should return the "parent" of the `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#current()` node at the beginning of this operation.

## Public properties

### current

Cmn Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.0.0)

```
val current: N
```

The node that operations will be applied on at any given time. It is expected that the value of this property will change as `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#down(kotlin.Any)` and `https://developer.android.com/reference/kotlin/androidx/compose/runtime/Applier#up()` are called.