Kotlin 2.4.0: Explicit Backing Fields
It’s time to update your Android View Models!
Kotlin 2.4.0: Explicit Backing Fields
It may be time to update your Android View Models!

Using an Explicit Backing Field (EBF) to represent ViewModel State in Android
When using Model-View-Intent (MVI) or Model-View-ViewModel (MVVM) patterns in Android, you will likely have state code similar to the following:
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
This uses a feature of Kotlin known as Backing Properties, which allows you to keep your mutable state private to the view model while permitting the view to observe an immutable copy of the state.
However, this can result in a lot of boilerplate code, especially in MVVM where you may have many pieces of observable state in the view model.
Kotlin 2.4.0 to the rescue!
In Kotlin version 2.4.0 the feature known as Explicit Backing Fields or “EBF” for short is now stable. With EBF you no longer need to define two separate properties for your state as demonstrated below:
val uiState: StateFlow<UiState>
field = MutableStateFlow(UiState.Loading)
When accessing uiState from inside of the view model, it will now be automatically smart-cast from StateFlow to MutableStateFlow allowing you to update the state without having to rely on any explicit casting:
// inside of the VM, uiState is smart-cast to MutableStateFlow, yay!
uiState.update {
it.copy(
state = UiState.Loaded,
)
}
Issues and Limitations
It should be noted that I have observed the following issue when using the EBF language feature, but it is possible that I am missing something:
- When using the traditional approach for managing view model state, backing properties coupled with
asStateFlow(), if you try to cast the state in the view to aMutableStateFlowthen you will get aClassCastExceptioneffectively ensuring that the view model state is indeed private. Unfortunately with EBF, you can cast the state in the view and everything will work fine. This behavior is similar to if you had omitted the call toasStateFlow()when using backing properties.
This means that something like the following will unfortunately work fine at runtime which seems like an issue to me.
// the view is able to cast the view model state field <sad> :(
(viewModel.uiState as MutableStateFlow<UiState>).update {
it.copy(
state = UiState.Loaded,
)
}
Documented Limitations
There are also documented limitations of this language feature which can be found here (and they are also depicted below).

Documented Limitations of Explicit Backing Fields
Conclusion
If you want to eliminate some of the boilerplate code often found in Android view models, then it may be a good time to give Explicit Backing Fields (EBF), now stable in Kotlin 2.4.0, your consideration.
메타데이터
- post_id
- 5c38d6b6eea3
- slug
- kotlin-2-4-0-explicit-backing-fields-5c38d6b6eea3
- url
- https://medium.com/@thomas-sunderland/kotlin-2-4-0-explicit-backing-fields-5c38d6b6eea3
- canonical_url
- https://medium.com/@thomas-sunderland/kotlin-2-4-0-explicit-backing-fields-5c38d6b6eea3
- author_url
- https://medium.com/@thomas-sunderland
- status
- ok
- fetched_at
- 2026-06-12 07:40:50