{"id":29829896,"url":"https://github.com/chrynan/navigation","last_synced_at":"2025-07-29T09:41:53.446Z","repository":{"id":65458724,"uuid":"439481580","full_name":"chRyNaN/navigation","owner":"chRyNaN","description":"Kotlin multi-platform application navigation library.","archived":false,"fork":false,"pushed_at":"2023-07-28T18:52:38.000Z","size":777,"stargazers_count":33,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2023-07-28T19:41:32.025Z","etag":null,"topics":["android","jetpack-compose","jetpack-navigation","kotlin","kotlin-library","kotlin-multi-platform","kotlin-multiplatform","kotlin-multiplatform-library","kotlin-multiplatform-mobile","nav","navigation","navigation-architecture-component","navigation-component"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chRyNaN.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-17T23:07:21.000Z","updated_at":"2023-07-28T13:24:49.000Z","dependencies_parsed_at":"2023-01-24T14:45:36.609Z","dependency_job_id":null,"html_url":"https://github.com/chRyNaN/navigation","commit_stats":null,"previous_names":[],"tags_count":11,"template":null,"template_full_name":null,"purl":"pkg:github/chRyNaN/navigation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fnavigation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fnavigation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fnavigation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fnavigation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chRyNaN","download_url":"https://codeload.github.com/chRyNaN/navigation/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chRyNaN%2Fnavigation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267665428,"owners_count":24124533,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","jetpack-compose","jetpack-navigation","kotlin","kotlin-library","kotlin-multi-platform","kotlin-multiplatform","kotlin-multiplatform-library","kotlin-multiplatform-mobile","nav","navigation","navigation-architecture-component","navigation-component"],"created_at":"2025-07-29T09:41:34.747Z","updated_at":"2025-07-29T09:41:53.436Z","avatar_url":"https://github.com/chRyNaN.png","language":"Kotlin","funding_links":["https://www.buymeacoffee.com/chrynan"],"categories":[],"sub_categories":[],"readme":"![navigation](assets/navigation_logo.png)\n\n# navigation\n\nKotlin multi-platform application navigation library that supports Jetpack Compose. \u003cbr/\u003e\u003cbr/\u003e\n\u003cimg alt=\"GitHub tag (latest by date)\" src=\"https://img.shields.io/github/v/tag/chRyNaN/navigation\"\u003e\n\n```kotlin\nval navigator = rememberNavigator(initialDestination = \"Greeting\")\n\nNavigationContainer(navigator) { (destination, _) -\u003e\n    when (destination) {\n        \"Greeting\" -\u003e Column {\n            Text(\"Hello\")\n\n            Button(onClick = { navigator.push(\"Farewell\") }) {\n                Text(\"Say Goodbye\")\n            }\n        }\n        \"Farewell\" -\u003e Text(\"Good-bye\")\n        else -\u003e Text(\"Unexpected Destination: $destination\")\n    }\n}\n```\n\n## Getting Started 🏁\n\nThe library is provided through [Repsy.io](https://repsy.io/). Checkout\nthe [releases page](https://github.com/chRyNaN/navigation/releases) to get the latest version. \u003cbr/\u003e\n\u003cimg alt=\"GitHub tag (latest by date)\" src=\"https://img.shields.io/github/v/tag/chRyNaN/navigation\"\u003e\n\n### Repository\n\n```groovy\nrepositories {\n    maven {\n        url = uri(\"https://repo.repsy.io/mvn/chrynan/public\")\n    }\n}\n```\n\n### Dependencies\n\n#### core\n\n```groovy\nimplementation(\"com.chrynan.navigation:navigation-core:VERSION\")\n```\n\n#### compose\n\n```groovy\nimplementation(\"com.chrynan.navigation:navigation-compose:VERSION\")\n```\n\n## Usage 👨‍💻\n\n### Destinations\n\n`NavigationDestinations` represent the locations within an application that a `Navigator` can coordinate. They can be of\nany type and can contain any data that is useful to render the destination UI. A common approach is to use enums or\nsealed classes to represent the different `NavigationDestinations` within an application.\n\n```kotlin\nenum class AppDestination {\n\n    HOME,\n    SEARCH,\n    SETTINGS,\n    DETAILS\n}\n```\n\n### Contexts\n\nA `NavigationContext` is a way of representing complex or nested navigation destinations. A `NavigationContext` defines\nits `initialDestination` and has its own stack of `NavigationDestinations` associated with it within the internal\nimplementation of a `Navigator`. This allows there to be a stack of stacks of `NavigationDestinations` for an\napplication.\n\n```kotlin\nenum class MainContext(\n    override val initialDestination: AppDestination,\n    val title: String,\n    val icon: ImageVector\n) : NavigationContext\u003cAppDestination\u003e {\n\n    HOME(title = \"Home\", icon = Icons.Default.Home, initialDestination = AppDestination.Home),\n\n    SEARCH(title = \"Search\", icon = Icons.Default.Search, initialDestination = AppDestination.Search),\n\n    SETTINGS(title = \"Settings\", icon = Icons.Default.Settings, initialDestination = AppDestination.Settings)\n}\n```\n\n### Navigator\n\nA `Navigator` is used to navigate between navigation contexts and destinations via the\nconvenient `push`, `popContext`, and `popDestination` functions. A `Navigator` can be obtained via one of the\nconstructor functions or the `remember`/`rememberSavable` functions when using Jetpack Compose/Multiplatform Compose.\n\n```kotlin\nval navigator = rememberNavigator(initialDestination = AppDestination.HOME)\n\nBackHandler { navigator.popDestination() }\n\nListItem(modifier = Modifier.clickable { navigator.push(AppDestination.DETAILS) })\n```\n\n### NavigationContainer\n\nThe `NavigationContainer` composable provides a convenient way to listening to destination and context state changes and\nrecomposing its content accordingly. Just provide a `Navigator` instance and a content composable.\n\n```kotlin\n@Composable\nfun App() {\n    val navigator = rememberNavigator(initialDestination = AppDestination.HOME)\n\n    NavigationContainer(navigator = navigator) { (destination, context) -\u003e\n        when (destination) {\n            AppDestination.HOME -\u003e HomeScreenComposable()\n            AppDestination.SEARCH -\u003e SearchScreenComposable()\n            AppDestination.SETTINGS -\u003e SettingsScreenComposable()\n            AppDestination.DETAILS -\u003e DetailsScreenComposable()\n        }\n    }\n}\n```\n\n### Transitions and animations\n\nYou have complete control over the composable functions that render the UI of the application and can use the Jetpack\nCompose library's transition and animation APIs to change between the navigation context and destination UIs. For more\nfine-grained control, create a custom composable replacing the `NavigationContainer` that handles transitions properly\nfor your application. Then just listen and react to the `Navigator.state` changes.\n\n```kotlin\n@Composable\nfun \u003cDestination : NavigationDestination, Context : NavigationContext\u003cDestination\u003e\u003e MyNavContainer(\n    navigator: Navigator\u003cDestination, Context\u003e,\n) {\n    val context = navigator.store.context.collectAsState()\n    val destination = navigator.store.destination.collectAsState()\n\n    // Render UI from context and destination values and apply any transition or animation desired.\n}\n```\n\n### Best Practices\n\n* Avoid passing a `Navigator` to `@Composable` functions and\n  instead [hoist the state](https://developer.android.com/jetpack/compose/state-hoisting).\n\n```kotlin\n@Composable\nfun App() {\n  val navigator = rememberNavigator(...)\n\n  ...\n\n  MyScreen(\n    onBackPressed = { navigator.popDestination() },\n    onGoToDetails = { navigator.push(AppDestination.Details(it)) }\n  )\n}\n```\n\n* Use different `Navigators` for deep nested navigation. This way each component can retain its own navigation hierarchy\n  and delegate to its encapsulating component via state hoisting if it cannot handle the navigation.\n\n```kotlin\n@Composable\nfun ParentComponent() {\n    val parentNavigator = rememberNavigator(...)\n\n    ...\n\n    ChildComponent(onBack = { parentNavigator.popDestination() })\n}\n\n@Composable\nfun ChildComponent(\n    onBack: () -\u003e Unit\n) {\n    val childNavigator = rememberNavigator(...)\n\n    BackHandler {\n        if (!childNavigator.canPopDestination()) {\n            onBack.invoke()\n        }\n    }\n}\n```\n\n* Use the `rememberSavableNavigator` function along with serializable navigation destinations and contexts to retain the\n  navigation state between configuration changes.\n\n```kotlin\nval navigator = rememberSavableNavigator(\n    initialContext = MainContext.HOME,\n    destinationSerializer = AppDestination.serializer(),\n    contextSerializer = MainContext.serializer()\n)\n```\n\n* Create the `Navigator` instance outside of `@Composable` functions to handle navigation outside the user interface\n  flow, such as in Activity lifecycle callbacks.\n\n```kotlin\nval navigator = Navigator(initialContext = MainContext.HOME)\n```\n\n* Utilize [side-effects](https://developer.android.com/jetpack/compose/side-effects) in Jetpack Compose for handling\n  navigation to non-composable UI components, such as starting new Activities or changing Fragments.\n\n```kotlin\nNavigationContainer(navigator) { (destination, _) -\u003e\n    when (destination) {\n        is AppDestination.Details -\u003e LaunchedEffect(destination) {\n            context.startActivity(DetailsActivity.newIntent(context, destinatin.id))\n        }\n    }\n}\n```\n\n* Utilize [kotlinx serialization](https://github.com/Kotlin/kotlinx.serialization) and\n  the [serialization-parcelable](https://github.com/chRyNaN/serialization-parcelable) library to transfer a `Navigator`\n  between components.\n\n```kotlin\nval navigatorSerializer = Navigator.serializer(destinationSerializer, contextSerializer)\n\nparcelable.encodeToParcel(serializer = navigatorSerializer, value = navigator)\njson.encodeToString(serializer = navigatorSerializer, value = navigator)\n```\n\n## Documentation 📃\n\nMore detailed documentation is available in the [docs](docs/) folder. The entry point to the documentation can be\nfound [here](docs/index.md).\n\n## Security 🛡️\n\nFor security vulnerabilities, concerns, or issues, please responsibly disclose the information either by opening a\npublic GitHub Issue or reaching out to the project owner.\n\n## Contributing ✍️\n\nOutside contributions are welcome for this project. Please follow the [code of conduct](CODE_OF_CONDUCT.md)\nand [coding conventions](CODING_CONVENTIONS.md) when contributing. If contributing code, please add thorough documents.\nand tests. Thank you!\n\n## Sponsorship ❤️\n\nSupport this project by [becoming a sponsor](https://www.buymeacoffee.com/chrynan) of my work! And make sure to give the\nrepository a ⭐\n\n## License ⚖️\n\n```\nCopyright 2023 chRyNaN\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrynan%2Fnavigation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrynan%2Fnavigation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrynan%2Fnavigation/lists"}