A user reported that the app kept resetting to light mode on every restart even though they'd set it to dark. The bug was embarrassingly simple: I was only updating a StateFlow . The ViewModel emitted the new theme, Compose recomposed, everything looked correct — until the process died. On the next cold start, the MutableStateFlow initialised with a hardcoded default and the persisted preference was never read. That's the most common Compose dark mode bug. This post covers the full production pattern that prevents it. Start With an Enum, Not a Boolean A Boolean gives you light or dark. Users need a third option: follow the system. enum class ThemeMode ( val value : Int ) { LIGHT ( 0 ), DARK ( 1 ), SYSTEM ( 2 ) } Enter fullscreen mode Exit fullscreen mode SYSTEM as the default ( value = 2 ) is the right out-of-the-box experience. Storing .value as an Int keeps SharedPreferences simple.…