On Toolbox, I migrated substantial UI from XML to Jetpack Compose while continuing to deliver features for an Android application with everyday utilities and home-screen widgets.
The goal was not to rewrite the entire application at once. The goal was to modernize the UI without making releases less predictable.
Choose one boundary at a time
A safer migration starts with one utility surface. Define its state, events, loading behavior, and error states before replacing the UI layer.
Old and new screens can coexist while behavior is compared. This reduces the size of each change and makes regressions easier to isolate.
Keep state ownership clear
Each feature should own the state it needs. Shared settings and navigation should remain at an appropriate higher boundary. Clear ownership prevents unrelated utilities from being invalidated by a local update.
Measure before and after
After each migration step, check startup behavior, crashes, accessibility, scrolling, and the most-used flows. A visually modern screen is not an improvement if it makes the product harder to use or release.
The practical lesson is to migrate incrementally, preserve working behavior, and let measured results determine the next step.
Source: Jetpack Compose performance