Skip to content
No description, website, or topics provided.
Branch: master
Clone or download

Latest commit


Type Name Latest commit message Commit time
Failed to load latest commit information.
.idea Updated to compose dev07 Mar 20, 2020
core Added maven plugin to core Mar 3, 2020
gradle/wrapper Updated to compose dev07 Mar 20, 2020
navigation Artifact test Mar 3, 2020
sample Updated to dev06 Mar 6, 2020
.gitignore Initial commit Mar 3, 2020 Update Mar 3, 2020
build.gradle Updated to compose dev07 Mar 20, 2020 Initial commit Mar 3, 2020
gradlew Initial commit Mar 3, 2020
gradlew.bat Initial commit Mar 3, 2020


  • Navigate completely within Jetpack Compose
  • Use Router as any other composable
  • Nest Routers however you like to support split screens or bottom tabs
  • Each Router you add will have its own back stack
  • Back stack is handled for you no matter how complex your navigation is


Add Jitpack repository to your top level build.gradle:

allprojects {
    repositories {
        maven { url '' }

Add dependency in your app build.gradle:

implementation 'com.github.mvarnagiris.compose-navigation:navigation:{latest_version}'

How to use

Inside your Activity tell library to handle back stack:

override fun onBackPressed() {
    if (!backStackController.pop()) super.onBackPressed()

Define your navigation routes. Best way to do that is to use a sealed class. Each route can contain all necessary parameters for your screens:

sealed class AppRoute {
    object SplashRoute : AppRoute()
    object HomeRoute : AppRoute()
    data class DetailsRoute(val id: String) : AppRoute()

Wherever you want routing to happen add Router:

fun AppRoot() {
    Router<AppRoute>(start = SplashRoute) { currentRoute ->
        // this lambda has this signature: BackStack<AppRoute>.(Route<AppRoute>) -> Unit
        // this is BackStack<AppRoute>. So you can call BackStack methods easily like push(...), pop(), etc.
        // currentRoute is Route<AppRoute> that contains current AppRoute as data and other metadata like index and back stack identifier
        when (val route = {
            SplashRoute -> SplashScreen(onInitialized = { replace(HomeRoute) })
            HomeRoute -> HomeScreen(onDetailsSelected = { id -> push(DetailsRoute(id)) })
            is DetailsRoute -> DetailsScreen(

fun SplashScreen(onInitialized: () -> Unit) {
    // ...

fun HomeScreen(onDetailsSelected: (String) -> Unit) {
    // ...

fun DetailsScreen(id: String) {
    // ...

BackStack operations:

  • push - push one or more routes into the back stack
  • pop - remove top most route from the back stack. It will not remove last route
  • replace - replace top most route with zero or more routes
  • replaceRoute - replace specific route with zero or more routes

backStackController.pop() will pop from global back stack. Each Router has it's own BackStack and all of them are controlled by backStackController which has global back stack

For more examples check out the sample app

You can’t perform that action at this time.