---
title: "Promise compose compiler and imply when you'll change 🤞 | Shreyas Patil's Blog"
description: "Understand the Compose compiler's stability promises. Learn how @Stable and @Immutable impact recomposition and how to help the compiler optimize your UI."
image: "https://blog.shreyaspatil.dev/_astro/cover-promise-compose-compiler-and-imply-when-youll-change.DaTz17b5.png"
---

# Promise compose compiler and imply when you'll change 🤞

Hey Droid-folks and Composers 👋, this is a mini-blog where we’ll discuss improving the performance of Composables by taking care and promising some things to the Compose Compiler.

Let’s say you’re composing your UI and the composable function looks like this 👇:

```
@Composable
fun PersonInfo(person: Person) {
    // ...
}
```

In this, let’s assume you have a `Person` UI model like this:

```
class Person(
    val name: String,
    val email: String,
    val mobileNumber: String,
    val age: Int,
    val skills: List<String>,
    val organization: Organization
)
```

The above `@Composable` function is responsible for showing `Person`’s information. Let’s assume you’ve `List<Person>` and you’re showing it inside `LazyRow` / `LazyColumn`. While implementing it, sometimes you may notice that there’s something that is lagging on UI.

The function `PersonInfo` will be recomposed whenever the parameter `Person` is changed.

You can simply tell compose a compiler about when you’ll change and optimize the performance, do you know?

---

## 🤔 How?

The compose runtime library has provided two annotations by which we can imply compose compiler about model’s behavior. This affects the binary compatibility of code generated by the Compose compiler plugin by which compose does optimizations and it may help to improve the performance of your application.

### 1. `@Immutable` Annotation

- `Immutable` can be used to mark a class that produces immutable instances. In short, a class that has all public fields declared as `val`.

- This is a promise to the compose compiler that once the object is constructed, the properties inside it won’t change at runtime.

- Immutable is used by a composition that enables composition optimizations that can be performed based on the assumption that values read from the type will not change.

- `data class` that only contains `val` properties that do not have custom getters can safely be marked as `Immutable` if the types of properties are either primitive types or also `Immutable`.

Let’s revise our UI model:

```
+ @Immutable
+ data class Person(
      val name: String,
      val email: String,
      val mobileNumber: String,
      val age: Int,
      val skills: List<String>,
      val organization: Organization
  )
```

Here, after adding annotation `@Immutable` we also have to make sure that the field `organization` of type `Organization` should also be annotated with `@Immutable`.

---

### 2. `@Stable` Annotation

`Stable` is used to communicate guarantees to the compose compiler about how a certain type or function will behave. `Stable` annotation indicates that the function will return the same result if the same parameters are passed in. This is only meaningful if the parameters and results are themselves `Stable`, `Immutable`, or primitive.

When any class is annotated with `@Stable` it promises:

- The result of `equals()` will always return the same result for the same two instances.

- When a public property of the type changes, the composition will be notified.

- All public property types are stable.

The invariants that this annotation implies are used for optimizations by the compose compiler and have undefined behavior if the above assumptions are not met. As a result, we should not use this annotation unless they are certain that these conditions are satisfied.

This annotation has to be applied to a type that indicates a type that is **mutable** and may change during runtime after the instance is created, but the compose runtime will be notified about the change in public properties. It’ll be only notified when the result of the previous invocation and change is different.

Let’s say in our `Person` model, we have a case where we want to support a change of organization at runtime. So want to make `organization` a mutable field with a kind of `State<Organization>` or `MutableState<Organization>` which can be changed at any time. Also, since we are using `data class`, we won’t need to worry about overriding the `equals()` method. *But if you’re not using a data class, make sure you override it.*

```
+ @Stable
+ data class Person(
      val name: String,
      val email: String,
      val mobileNumber: String,
      val age: Int,
      val skills: List<String>,
+     val organization: State<Organization>
  )
```

In short, whenever we are exposing reactive types in the UI model, they should be annotated with `@Stable` annotation.

---

## 🤔 Remember

Implementing such contract incorrectly for a type annotated as `@Stable` or `@Immutable` will result in incorrect behavior for `@Composable` functions that accept that type as a parameter or receiver and it may lead to issues. So use it wisely and check if you’re doing it in the right way.

That’s all, now just do these changes and run your app and see if there are improvements 😃.

---

That’s all, I hope you found this helpful.

*“Sharing is caring”*

Thank you! 😀

---

## 📚 References

- [Compose API Guidelines](https://github.com/androidx/androidx/blob/androidx-main/compose/docs/compose-api-guidelines.md)

- [Immutable - Compose Runtime Docs](https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable)

- [Stable - Compose Runtime Docs](https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable)

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Promise compose compiler and imply when you'll change 🤞 | Shreyas Patil's Blog",
  "image": "https://blog.shreyaspatil.dev/_astro/cover-promise-compose-compiler-and-imply-when-youll-change.DaTz17b5.png",
  "datePublished": "2022-03-10T12:42:38.498Z",
  "author": [
    {
      "@type": "Person",
      "name": "Shreyas Patil",
      "url": "https://shreyaspatil.dev/"
    }
  ],
  "keywords": "android-app-development, android, ui, kotlin, kotlin-beginner"
}

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://blog.shreyaspatil.dev/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Posts",
      "item": "https://blog.shreyaspatil.dev//posts/"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Promise compose compiler and imply when you'll change 🤞"
    }
  ]
}
```
