Nav3-Router Replaces ARouter with a KSP-Powered, Dual-Track Navigation Framework for Compose
ARouter's reflection and Activity-centric model is a dead end in the single-Activity, Compose-first world. Nav3-Router gives teams a drop-in path to Navigation 3 that doesn't sacrifice the dynamic URL routing and deep-link dispatch product teams rely on, while adding compile-time safety checks that catch duplicate routes before they ship.
Nav3-Router replaces ARouter's Activity/XML and reflection-based approach with a dual-track routing framework built on Android's Navigation 3 and KSP. It enforces type safety at compile time while still supporting dynamic URL navigation, and it layers on production necessities: automatic navigation-stack restoration after process death, a 404 fallback route to prevent white screens, and a chain-of-responsibility handler for intercepting H5 links or custom schemes. Multi-module setup requires zero Gradle configuration—KSP scans sub-modules and generates unique extension functions on NavCenter.
The framework introduces a decorator onion-skin system via NavEntryDecorator for injecting ViewModel scoping and analytics, alongside a global overlay mechanism that lets any module show a Compose dialog above the current page without pushing a new route. A green-channel option bypasses all interceptors for emergency direct navigation, and a service-discovery system using @Service and IService enables zero-reflection, cross-module calls for UI-less business logic like payment processing.
Shared-element morphing transitions, required-parameter runtime guards, and a pure-Kotlin testable Navigator abstraction round out the offering. The library is published to Maven Central under Apache 2.0.
Baking process-death restoration into the router itself, rather than leaving it as an exercise for each team, removes one of the most persistent sources of subtle crashes in Android apps.
The dual-track design—compile-time type safety via KSP for declared screens plus runtime URL strings for dynamic links—acknowledges that real apps need both, and that forcing one model exclusively creates friction.
Generating per-module init functions through KSP instead of requiring manual Gradle wiring sidesteps the configuration drift that plagues large multi-module projects as teams add and remove feature modules.
The overlay system treats dialogs as a first-class navigation concern independent of the backstack, which matches how product flows actually work: a payment sheet shouldn't be a new page in the user's mental model or the system back button's history.
Service discovery with @Service and IService fills a gap that pure navigation frameworks ignore—componentized apps need to call logic across module boundaries without creating compile-time dependency cycles, and doing it through the router's registry avoids yet another DI framework.