{"id":15040898,"url":"https://github.com/eranboudjnah/cleanarchitectureforandroid","last_synced_at":"2025-07-03T17:35:31.331Z","repository":{"id":179007927,"uuid":"662551018","full_name":"EranBoudjnah/CleanArchitectureForAndroid","owner":"EranBoudjnah","description":"Clean Architecture for Android - a sample project","archived":false,"fork":false,"pushed_at":"2025-06-28T15:54:20.000Z","size":4811,"stargazers_count":742,"open_issues_count":2,"forks_count":83,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-06-28T16:48:49.044Z","etag":null,"topics":["android","android-app","android-architecture","android-development","android-testing","architectural-patterns","clean-architecture","clean-architecture-android","espresso","gradle-kotlin-dsl","hilt-android","jetpack-compose","kotlin-android","kotlin-coroutines","mobile-development","multi-module-project","multimodule-android-app","multimodule-kotlin-app","mvvm"],"latest_commit_sha":null,"homepage":"https://amzn.to/3rBSxOb","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/EranBoudjnah.png","metadata":{"files":{"readme":"README.md","changelog":"history/data/build.gradle.kts","contributing":null,"funding":"FUNDING.yml","license":"LICENSE","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},"funding":{"github":"EranBoudjnah","custom":"https://paypal.me/EranB"}},"created_at":"2023-07-05T11:27:16.000Z","updated_at":"2025-06-28T15:54:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"fbe9d1af-882c-4e01-a188-315ea82da50f","html_url":"https://github.com/EranBoudjnah/CleanArchitectureForAndroid","commit_stats":{"total_commits":328,"total_committers":3,"mean_commits":"109.33333333333333","dds":0.3140243902439024,"last_synced_commit":"7fb121ca3e7093558cd881770e1048dbed344867"},"previous_names":["eranboudjnah/cleanarchitectureforandroid"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/EranBoudjnah/CleanArchitectureForAndroid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EranBoudjnah%2FCleanArchitectureForAndroid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EranBoudjnah%2FCleanArchitectureForAndroid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EranBoudjnah%2FCleanArchitectureForAndroid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EranBoudjnah%2FCleanArchitectureForAndroid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EranBoudjnah","download_url":"https://codeload.github.com/EranBoudjnah/CleanArchitectureForAndroid/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EranBoudjnah%2FCleanArchitectureForAndroid/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263370158,"owners_count":23456423,"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","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","android-app","android-architecture","android-development","android-testing","architectural-patterns","clean-architecture","clean-architecture-android","espresso","gradle-kotlin-dsl","hilt-android","jetpack-compose","kotlin-android","kotlin-coroutines","mobile-development","multi-module-project","multimodule-android-app","multimodule-kotlin-app","mvvm"],"created_at":"2024-09-24T20:45:15.382Z","updated_at":"2025-07-03T17:35:31.307Z","avatar_url":"https://github.com/EranBoudjnah.png","language":"Kotlin","funding_links":["https://github.com/sponsors/EranBoudjnah","https://paypal.me/EranB"],"categories":[],"sub_categories":[],"readme":"# Clean Architecture for Android Sample Project\n\n[![Clean Architecture for Android](https://github.com/EranBoudjnah/CleanArchitectureForAndroid/blob/readme_assets/readme-assets/book_cover.jpg?raw=true\u0026123 \"Clean Architecture for Android\")](https://amzn.to/43cUuhb \"Clean Architecture for Android\")\n![Screenshot](https://github.com/EranBoudjnah/CleanArchitectureForAndroid/blob/readme_assets/readme-assets/screenshot_1692005135.png?raw=true\u00261 \"Screenshot\")\n\nThis project is a loose implementation of Clean Architecture as presented in my book,\n[Clean Architecture for Android](\nhttps://amzn.to/43cUuhb). It is a native Android project written in Kotlin. It demonstrates\nthe key principles presented in the book and how they apply to a real life project.\n\nI will endeavour to keep this project up to date and use it to demonstrate the strengths of the\narchitecture: **scalability**, **testability** and **flexibility** when it comes to choosing 3rd\nparty solutions.\n\n### Features\n\n- Feature separation\n- Layer separation\n    - UI\n    - Presentation\n    - Domain\n    - Data\n    - Data Source\n- Dummy analytics\n- Navigation\n- Animations\n- Unit tests\n- End-to-end tests\n- Demonstrates use of [Jetpack Compose](https://developer.android.com/jetpack/compose)\n- Demonstrates use of [Coroutines](https://kotlinlang.org/docs/coroutines-overview.html)\n  including [Flow](https://kotlinlang.org/docs/flow.html)\n- Demonstrates \u003cabbr title=\"Model View ViewModel\"\u003eMVVM\u003c/abbr\u003e\n- Code quality checks using [ktlint](https://github.com/pinterest/ktlint)\n- Code quality checks using [detekt](https://github.com/detekt/detekt)\n- Architecture consistency checks\n  using [konsist](https://docs.konsist.lemonappdev.com/getting-started/readme)\n- Continuous integration (CI) using [GitHub Actions](https://github.com/features/actions)\n    - Unit tests\n    - Instrumentation tests\n    - Linting\n\n### Choices\n\n- **Simplicity**\n\n  \"*The complexity introduced here is an overkill!*\"\n\n  I agree. If this was to be a **final** project, to which no new functionality would\n  ever be added, then *Clean Architecture* would have been overly complicated for it.\n  However, the reality is that mobile project seldom **are** final. User feedback,\n  marketing requirements, new technologies - these factors and others all lead to\n  continuous changes to almost every project. And so, what may now seem like too\n  much complexity will reward us when the time for change comes. This will be\n  when *Clean Architecture* shines.\n\n  As a side note: in some ways, I have *intentionally* over-complicated this project\n  by introducing different technologies. The goal was to show how, even in real-life\n  scenarios, where a project may have grown over time to include more than one\n  technological solution, the architecture still works.\n\n- ***Mappers as classes*** **vs.** ***mapping extension functions***\n\n  When mapping between models, we have several options. The primary decision is\n  between mapper classes and mapping extension functions.\n\n  While extension functions are more concise, using them for mapping limits our choices of\n  testing frameworks ([Mockito](\n  https://site.mockito.org/), for example, cannot stub static functions).\n\n  How about injecting the mapper extension functions? We could do that. However, this\n  removes the benefits of conciseness almost entirely. It also makes navigation to the\n  implementation harder.\n\n  And so, I opted for the slightly more verbose concrete mapper classes.\n\n- **Skipping Google's [Architecture Components](\n  https://developer.android.com/reference/androidx/lifecycle/package-summary)**\n\n  The greatest issue with Google's Architecture Components is that they leak Android\n  details into the Presentation layer. This prevents the Presentation layer from being\n  truly UI agnostic.\n\n  Another issue with the Architecture Components is that they give too much responsibility\n  to the ViewModel. They make it persist state it does not own, leading to potential data\n  synchronization bugs.\n\n  For these reasons, while still following MVVM, this project relies on **Kotlin Flows** rather\n  than **LiveData**, and implements pure ViewModels rather than Google's.\n\n- **Mocking framework**\n\n  Both [Mockito-Kotlin](https://github.com/mockito/mockito-kotlin) and [Mockk](\n  https://mockk.io/) are used in this project to demonstrate how the use of each would look.\n\n  My personal preference remains **Mockito-Kotlin**. I find the code easier to read and follow\n  when using it. At the time of writing, judging by the number of stars on each repository,\n  the industry seems to lean towards Mockk.\n\n  I was asked about using *fakes*. I have explored fakes, and found them to be overly verbose\n  and too expensive to maintain.\n\n- **Dependency injection framework**\n\n  A critical part of most modern apps, dependency injection (DI) helps us obtain the objects\n  that build our app. It also helps manage their scope. The most popular choices in the\n  Android world are [Hilt](https://dagger.dev/hilt/) (which is built on top of [Dagger](\n  https://dagger.dev/)) and [Koin](https://insert-koin.io/).\n\n  **Hilt** was chosen for two main reasons:\n    1. **Compile time safety** - having the confidence that all my dependencies are provided\n       before the app starts is a huge time saver and helps maintain a stable app.\n    2. **Simplicity** - from experience, setting up and using Hilt (unlike the underlying Dagger)\n       is considerably easier than using Koin. Hilt also introduces fewer breaking changes\n       over time.\n\n- ***XML*** **vs** ***Jetpack Compose***\n\n  Why not both? I still have a lot of concerns around **Jetpack Compose**. Even so, it was\n  important to me to show the presented architecture works well regardless of the UI\n  mechanism chosen. As an exercise, I invite you to try and replace the UI layer from Compose\n  to XML or vice versa without updating the Presentation layer.\n\n### Links\n\n[Clean Architecture for Android on Amazon](https://amzn.to/43cUuhb \"Clean Architecture for Android\")\n\n[Clean Architecture on the Clean Coder Blog](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html \"Clean Architecture\")\n\n### Contributing\n\nContributions to this project are welcome. Please feel free to report any issues or fork to\nmake changes and raise a pull request.\n\n### Licence\n\nThis project is distributed under the terms of the MIT License. See [LICENSE.md](LICENSE) for\ndetails.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feranboudjnah%2Fcleanarchitectureforandroid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feranboudjnah%2Fcleanarchitectureforandroid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feranboudjnah%2Fcleanarchitectureforandroid/lists"}