DEV Community

Cover image for Retain API in Jetpack Compose
Saidur Rahman
Saidur Rahman

Posted on

Retain API in Jetpack Compose

Mastering the Retain API in Jetpack Compose: Why & How It Matters

In modern Android development with Jetpack Compose, managing state effectively — especially across configuration changes — is crucial for building resilient and fluid UI experiences. That’s where the Retain API comes in.

In this article, we’ll explore:

🔹 What the Retain API is
🔹 Why it matters
🔹 How to use it with examples
🔹 Best practices
🔹 Helpful resources


What is the Retain API?

The Retain API in Jetpack Compose lets you preserve state across configuration changes like device rotation, process death, and navigation lifecycle events — without relying on manual save/restore logic.

Unlike typical remember or mutableStateOf, which hold state only during composition lifetime, the Retain API ties state to the lifecycle owner (e.g., ViewModel, NavBackStackEntry), ensuring it survives events like rotation.


Why Use the Retain API?

Here’s why the Retain API is a game-changer:

Survives configuration changes (e.g., screen rotation)
Works with process death restoration
Integrates with ViewModels & Navigation
✅ More concise and Compose-friendly than onSaveInstanceState

It simplifies state persistence without boilerplate, so you can focus on building features.


Core Concepts

There are three key building blocks:

API Purpose
rememberRetained Persists state across composition & config changes
RetainedSaveableStateRegistry Handles the save/restore lifecycle
SavedStateHandle Works with ViewModels for state persistence

Example: Persist Form State with Retain API

Let’s say you have a simple form that you want to keep alive across rotations.

Without Retain API (Problem)

@Composable
fun ProfileForm() {
    var name by remember { mutableStateOf("") }
    var email by remember { mutableStateOf("") }

    Column {
        TextField(value = name, onValueChange = { name = it }, label = { Text("Name") })
        TextField(value = email, onValueChange = { email = it }, label = { Text("Email") })
    }
}
Enter fullscreen mode Exit fullscreen mode

The moment the device rotates, the state is lost.


With Retain API

@Composable
fun ProfileFormRetained() {
    val retainedState = rememberRetained { mutableStateOf("") }
    val (name, setName) = retainedState

    val retainedEmail = rememberRetained { mutableStateOf("") }
    val (email, setEmail) = retainedEmail

    Column {
        TextField(value = name, onValueChange = setName, label = { Text("Name") })
        TextField(value = email, onValueChange = setEmail, label = { Text("Email") })
    }
}
Enter fullscreen mode Exit fullscreen mode

Now the state survives rotation — and you write less code.


Using Retain API with ViewModel

If you’re using a ViewModel, you can store the retained state inside it:

class ProfileViewModel(
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    var name by savedStateHandle.getState("name") { "" }
    var email by savedStateHandle.getState("email") { "" }
}
Enter fullscreen mode Exit fullscreen mode

In Compose:

@Composable
fun ProfileScreen(vm: ProfileViewModel = hiltViewModel()) {
    TextField(value = vm.name, onValueChange = { vm.name = it }, label = { Text("Name") })
    TextField(value = vm.email, onValueChange = { vm.email = it }, label = { Text("Email") })
}
Enter fullscreen mode Exit fullscreen mode

This ensures even process death restoration, not just rotation persistence.


Best Practices

✨ Favor rememberRetained for UI state that must survive recomposition
✨ Use SavedStateHandle with ViewModel for process death and navigation state
✨ Scope retained state to where it logically belongs (e.g., ViewModel vs Composable)


Resource Links

Here are official resources to deepen your knowledge:

🔗 Android Dev — Jetpack Compose State & State Hoisting
https://developer.android.com/jetpack/compose/state

🔗 SavedStateHandle in ViewModel
https://developer.android.com/topic/libraries/architecture/viewmodel-savedstate

🔗 Jetpack Compose API Reference
https://developer.android.com/reference/kotlin/androidx/compose


Final Thoughts

The Retain API is one of those under-the-hood features that makes real-world Compose apps robust and maintainable. Whether you’re handling forms, navigation state, or UI flags, understanding how to retain state confidently will boost both developer productivity and user experience.

Happy Composing! 🎨📱

Top comments (0)