{"id":34728248,"url":"https://github.com/pablichjenkov/nav3-playground","last_synced_at":"2026-04-22T15:38:25.191Z","repository":{"id":304420506,"uuid":"1009922726","full_name":"pablichjenkov/nav3-playground","owner":"pablichjenkov","description":"Playing a bit with nav3","archived":false,"fork":false,"pushed_at":"2026-03-21T01:09:36.000Z","size":276,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-21T16:54:01.176Z","etag":null,"topics":["android","compose","compose-nav3","compose-navigation","metro","nav3"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pablichjenkov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-28T01:06:39.000Z","updated_at":"2026-03-21T01:09:40.000Z","dependencies_parsed_at":"2025-09-06T21:13:41.329Z","dependency_job_id":"727bf69f-77bd-44e6-bb11-ec53e6fe2150","html_url":"https://github.com/pablichjenkov/nav3-playground","commit_stats":null,"previous_names":["pablichjenkov/nav3-playground"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pablichjenkov/nav3-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pablichjenkov%2Fnav3-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pablichjenkov%2Fnav3-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pablichjenkov%2Fnav3-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pablichjenkov%2Fnav3-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pablichjenkov","download_url":"https://codeload.github.com/pablichjenkov/nav3-playground/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pablichjenkov%2Fnav3-playground/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32143666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T15:33:03.595Z","status":"ssl_error","status_checked_at":"2026-04-22T15:30:42.712Z","response_time":58,"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","compose","compose-nav3","compose-navigation","metro","nav3"],"created_at":"2025-12-25T02:34:47.165Z","updated_at":"2026-04-22T15:38:25.186Z","avatar_url":"https://github.com/pablichjenkov.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Nav3 Blocks\n\n### Project Architecture\n\n#### 1. Module Depepndencies\nThis project inter-modular dependency uses a Diamond shape dependency structure.\n\n\u003cimg width=\"700\" alt=\"Diamond-Arch\" src=\"https://github.com/user-attachments/assets/8d2b4e63-ccdf-4223-b11f-8f9a61affa3e\" /\u003e\n\nIn such architecture, feature modules do not depend directly on each other. They all depend on a **common** module which contains the public APIs each of this module exposes to its clients. On top of the diamond, you see the integrator module, this is the app module. It basically acts like a coordiantor between all the modules.\n\n#### 2. Nav3Block\nEach feature of this project provides a **Nav3Block** implementation to be consumed by a **TopLevel Nav3 Navigator**. A TopLevel navigator could be a NavigationDrawer navigator, a BottomBar navigator, a BottomSheet navigator, a Floating Buton + Floating Menu navigator, you pick. However, no matter what navigator is selected, the feature modules will behave the same and will adapt to each navigation type constraint.\nThat is the power of modulirization and componentization.\n\n### Navigation\nThis project uses google compose only **nav3** navigation library. In this architecture each module is responsible for its internal navigation. Some modules contain an internal NavDisplay as an example of **nested NavDisplays**.\n\u003cBR/\u003e\nThe integrator module on the top of the diamond, this one is in charge of the **General App/Module Navigation**. This top module is also in charge of tasks like **App Startup**, **Notifications Routing**, **DeepLink Routing** and such a global application stuff.\n\n### Dependency Injection\nThe DI framework of choice is Metro, go check the [Metro Repo](https://github.com/ZacSweers/metro), highly recommended.\n\u003cBR/\u003e\nIn the diamond architecture, each module exposes the public abstract API in common. Metro will bind the actual implementations from the feature modules or the app module.\n\u003cBR/\u003e\nBellow is a diagram representing how block classes are scoped in a block and how the block are scoped in the App scope.\n\n\n\u003cimg width=\"700\" height=\"1524\" alt=\"Screenshot 2026-03-21 at 9 48 47 PM\" src=\"https://github.com/user-attachments/assets/342ae27d-4d41-46cc-9aa7-d263dd3e6e8e\" /\u003e\n\n\n\u003cBR/\u003e\n\u003cBR/\u003e\nBelow is a more realistic representation of how a Block looks like.\n\u003cBR/\u003e\n\u003cBR/\u003e\n\n\u003cimg width=\"700\" alt=\"Screenshot 2026-03-06 at 4 02 20 PM\" src=\"https://github.com/user-attachments/assets/6a3d0633-024a-473a-bb23-6c9337aaa2d5\" /\u003e\n\n\nVisual representation of a **Nav3Block**.\n\u003cBR/\u003e\n\u003cBR/\u003e\nNotice the project does not use the term **SharedViewModel** but rather **SharedUiDataManager** or **SharedDataManager** or **SharedSateManagerr**. This is in purpose because in general the term \"SharedViewModel\" is not confusing. Confusing because the ViewModel pattern explicitly mention that **the relation between a View and a ViewModel is a One to One**. A SharedViewModel breaks this principle, because now the View will have its own ViewModels plus a shared one. So this project removes that terminology.\n\n### Demo\nIn the demo below you can notice how nested NavDisplays interact when the user visit the differenttabs and navigate deeply within them.\n\u003cimage width=\"330\" src=\"https://github.com/user-attachments/assets/69d541c5-5efe-4e5f-bd9f-1e5ee295eab2\"/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpablichjenkov%2Fnav3-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpablichjenkov%2Fnav3-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpablichjenkov%2Fnav3-playground/lists"}