{"id":13609531,"url":"https://github.com/esafirm/universal-router","last_synced_at":"2026-02-26T17:04:24.274Z","repository":{"id":40421620,"uuid":"134037751","full_name":"esafirm/universal-router","owner":"esafirm","description":"↩️ Router for every occasions","archived":false,"fork":false,"pushed_at":"2023-01-23T18:02:56.000Z","size":839,"stargazers_count":76,"open_issues_count":13,"forks_count":11,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-07T21:05:57.322Z","etag":null,"topics":["android-navigation","hacktoberfest","modular","navigation","router"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/esafirm.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":"2018-05-19T06:52:00.000Z","updated_at":"2024-02-19T04:01:35.000Z","dependencies_parsed_at":"2023-02-13T01:45:56.952Z","dependency_job_id":null,"html_url":"https://github.com/esafirm/universal-router","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/esafirm/universal-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esafirm%2Funiversal-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esafirm%2Funiversal-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esafirm%2Funiversal-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esafirm%2Funiversal-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esafirm","download_url":"https://codeload.github.com/esafirm/universal-router/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esafirm%2Funiversal-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29865428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T16:38:37.846Z","status":"ssl_error","status_checked_at":"2026-02-26T16:37:58.932Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-navigation","hacktoberfest","modular","navigation","router"],"created_at":"2024-08-01T19:01:35.699Z","updated_at":"2026-02-26T17:04:24.243Z","avatar_url":"https://github.com/esafirm.png","language":"Kotlin","readme":"# Universal Router\n\n![](https://github.com/esafirm/universal-router/workflows/androidci/badge.svg)\n\n\u003e Router for every ocassion ~\n\nUniversal router comes with two flavor, the core module which basically a link router that can convert your URI to whatever you need. And the Android module which more opinionated to how you can use it to help you solve your navigation problem\n\n## Download\n\nAdd this to your project `build.gradle`\n\n```groovy\nallprojects {\n    repositories {\n        maven { url \"https://jitpack.io\" }\n    }\n}\n```\n\nAnd add this to your module `build.gradle`\n\n```groovy\ndependencies {\n    implementation \"com.github.esafirm.universal-router:core:$routerVersion\"\n    implementation \"com.github.esafirm.universal-router:android:$routerVersion\"\n}\n```\n\n## Core\n\nIt basically consist of two router\n\n1. `SimpleRouter` which route `Any` type of object to anything you need\n2. `UrlRouter` which takes URI instead of object\n\n### Some Examples\n\n```kotlin\n// Define router\nclass StringRouter : UrlRouter\u003cString\u003e() {\n\n    init {\n        addEntry(\"nolambda://test/{a}/{b}\", \"https://test/{a}/{b}\") { _, param -\u003e\n            val first = param[\"a\"]\n            val second = param[\"b\"]\n            \"$second came to the wrong neighborhood $first\"\n        }\n    }\n}\n\n// Call router\n// This will return string \"you can to the wrong neighborhood yo\"\nStringRouter().resolve(\"nolambda://test/yo/you\")\n```\n\n\u003e For more sample, plese look at the `samples` directory.\n\n## Android\n\n\u003cimg src=\"https://raw.githubusercontent.com/esafirm/universal-router/master/art/diagram.png\"/\u003e\n\nBasically with just the `core` module you already can have a navigation system in your modular structured application (think dynamic module use case). The easiest way would be creating a `Singleton` router in your \"core\" module and then add entries in every other module, but this can get quite messy sometimes, this is when the android router module comes in.\n\nFirst let's define our project structure:\n\n```kotlin\nproject\n│\n├── app // Android app module, depends to all modules\n│\n├── cart // Feature cart, only depends to router\n│\n├── product // Feature product, only depends to router\n│\n└── approuter // Router libs that every module depends\n```\n\n\u003e In dynamic module use case the `cart` and `product` module would be depends the `app` module\n\nNext what you want to create is the list of the routes in the \"router\" module, in this case `approuter`\n\n```kotlin\nobject AppRouter {\n    // Simplest form of Route\n    object Home : Route()\n    // Route support deeplink navigation\n    object Cart : Route(\"https://bukatoko.com/cart\")\n    // Route also support navigation with parameter\n    object Product : RouteWithParam\u003cProduct.ProductParam\u003e(\n        paths = arrayOf(\"https://bukatoko.com/{product_id}\", \"app://product/{id}\"),\n    ) {\n        data class ProductParam(\n            val productId: String\n        )\n    }\n}\n```\n\nAfter that, you have to register your navigation logic to the `Route`\n\n```kotlin\nAppRouter.Cart.Register {\n    context.startActivity(Intent(context, CartScreen::class.java))\n}\n```\n\nIf you want to initiate this in startup and your module doesn't have the access to `Application` class you can use the initializer\n\n```kotlin\nclass CartRouterInitializer : RouterInitializer {\n    override fun onInit(appContext: Context) {\n        ... // do as above\n    }\n}\n```\n\nDon't forget to register this on manifest\n\n```xml\n\u003cprovider\n    android:name=\".CartRouterInitializer\"\n    android:authorities=\"nolambda.router.cart\"\n/\u003e\n```\n\nThis is actually it if your navigation logic nature is \"fire and forget\", but in case you have to get something back (like `Fragment`) and use it in other place you can use the `RouteProcessor\u003cT\u003e`\n\n```kotlin\n// Processor only process return that has the same type as passed class\n// In this case it will only process router that return Fragment\nRouter.addProcessor\u003cFragment\u003e {\n    supportManager.beginTransaction()\n        .replace(R.id.container, it)\n        .commit()\n}\n```\n\nAfter that you can use the `Router` to navigate your app\n\n```kotlin\n// This will trigger Cart register lambda\nRouter.push(AppRouter.Cart)\n\n// You can use the registered deeplink too\nRouter.goTo(\"https://bukatoko.com/cart\")\n```\n\nAnd that's it you got yourself a navigation system.\n\n\u003e I can't stress enough that you should check `samples` for better understanding of the library\n\n## What's Next\n\n- Navigation type (push, replace, pop)\n- Annotation auto register (It's partially working now)\n  \u001e\n\n## License\n\nMIT @ Esa Firman\n","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesafirm%2Funiversal-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesafirm%2Funiversal-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesafirm%2Funiversal-router/lists"}