How are people actually handling state in large Compose screens?
I'm genuinely curious how teams are handling this in larger apps, because I'm not convinced we've fully solved it.
Before Compose, MVVM/MVI gave us a fairly clear direction: keep the screen state in the ViewModel, expose it, render it, test the transitions.
With Compose, we now have local state, state hoisting, state holders, StateFlow, snapshot state, rememberSaveable, and plenty of different ways to split ownership.
That flexibility is useful, but on a large screen it can also get messy pretty quickly.
If you keep everything in one UiState, it can become huge and start coupling unrelated parts of the screen together.
If you split state too much, you can end up with ownership spread across the ViewModel, composables and state holders, which can make the screen harder to reason about as a team.
Then testing adds another layer. What do you keep centralized because it makes behaviour easier to test? What do you leave local because it is really just UI state? Where do side effects fit without turning the ViewModel into a coordinator for every tiny interaction?
I don't really have a strong answer here.
For people working on large Compose codebases with multiple engineers:
How are you structuring state today?
One UiState per screen? Multiple state objects? State holders? Mostly ViewModel state with some local Compose state?
And more importantly, has that approach actually held up well for testing, maintenance and team ownership?
Sometimes I wonder whether Compose solved the old state-management problems, or just gave us more ways to distribute them.