Turo Pavlo Stavytskyi Aug 23, 2022

Designing Jetpack Compose Architecture for a Gradual Transition from Fragments on Android

Article Summary

Turo's Android team faced a challenge: how to adopt Jetpack Compose without rewriting their entire fragment-based app overnight.

Staff Engineer Pavlo Stavytskyi shares how Turo designed an architecture that lets developers write pure Compose code while maintaining seamless compatibility with legacy fragments. The solution uses code generation and abstraction layers to hide complexity.

Key Takeaways

Critical Insight

Turo built a migration path where engineers write pure Compose code while code generation handles all fragment compatibility automatically.

The architecture is now open sourced as Nibel, and the implementation details reveal clever tricks with NavHost and fragment transactions.

About This Article

Problem

Turo's codebase had a type safety problem in navigation. The navigation module couldn't depend on feature modules, so developers had to use reflection and fully qualified class names to create screens.

Solution

Pavlo Stavytskyi's team built a Destinations concept using @UiExternalEntry annotations and Kotlin Symbol Processing. This generated type-safe factories that Dagger injected, removing the need for reflection-based boilerplate.

Impact

Engineers now navigate between screens with strongly-typed destination objects like navigateTo(VehicleDetailsDestination(...)). This gives them compile-time safety while keeping the modular architecture intact, which helps with build times.