A powerful KSP-based navigation generator for Compose Multiplatform Navigation 3. It automates route definitions, polymorphic serialization, and screen mapping to provide a type-safe, boilerplate-free navigation experience across Android, iOS, Desktop, and Web.
It includes:
- Automatic Route Discovery: Generates route objects/classes from your Composable screens.
- Auto-Serialization: Generates
SerializersModulefor polymorphic navigation state saving. - Boilerplate-Free Mapping: Generates the entire
when(key)block forNavDisplay. - Smart Parameter Mapping: Automatically maps Route data to Screen parameters.
- Per-Screen Actions: Automatically generates type-safe
Actionsclasses andCompositionLocalsfor screen callbacks. - Screen Wrappers: Easily apply common wrappers (like ViewModels or Providers) to groups of screens via annotations.
implementation("io.github.the-best-is-best:nav3-annotations:1.1.0")Add the KSP processor to your project:
dependencies {
add("kspCommonMainMetadata", "io.github.the-best-is-best:nav3-processor:1.1.0")
// Add for each target to ensure code visibility in IDE
add("kspAndroid", "io.github.the-best-is-best:nav3-processor:1.1.0")
add("kspIosArm64", "io.github.the-best-is-best:nav3-processor:1.1.0")
add("kspIosSimulatorArm64", "io.github.the-best-is-best:nav3-processor:1.1.0")
}./gradlew :shared:assemble@NavGenerate
interface Routes : NavKey@Target(AnnotationTarget.FUNCTION)
annotation class NavDestination(
val name: String = "", // Custom name for the route (e.g. "Splash")
val group: String = "", // Optional nesting group (e.g. "Secure")
val wrapper: String = "" // Optional wrapper function name (e.g. "SecureWrapper")
)@NavGenerate
interface Routes : NavKey@Composable
@NavDestination(name = "Home", group = "Secure", wrapper = "SecureWrapper")
fun HomeScreen(
x: Int, // Data: Automatically added to RoutesDestinations.Secure.Home
onDialogOpen: (Boolean) -> Unit // Action: Automatically added to RoutesHomeActions
) {
Text("Home Screen with value $x")
}@Composable
fun App() {
// rememberRoutesBackStack and RoutesDestinations are auto-generated
val backStack = rememberRoutesBackStack(initialKey = RoutesDestinations.Splash)
var isDialogOpen by remember { mutableStateOf(false) }
// RoutesHomeActions is auto-generated specifically for HomeScreen
val homeActions = RoutesHomeActions(
onDialogOpen = { isDialogOpen = it },
onBack = { backStack.removeLastOrNull() }
)
CompositionLocalProvider(LocalRoutesHomeActions provides homeActions) {
NavDisplay<Routes>(
backStack = backStack,
onBack = { backStack.removeLastOrNull() },
entryProvider = { key -> routesEntryProvider(key) } // Auto-generated mapper
)
}
}kotlin {
sourceSets.named("commonMain").configure {
// Ensure the IDE sees generated code
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
}
}- Generated code path:
build/generated/ksp/ - Full Type-Safety: Any change in screen parameters is immediately reflected in the generated routes and actions.
- Zero Manual Mapping: No more manual
polymorphic { subclass(...) }or hugewhenblocks. - Wrapper Support: The
wrapperfunction must take a single@Composable () -> Unitparameter namedcontent.