# MVVMTemplate: a Compose and Clean Architecture starting point for Android

> MVVMTemplate is an MIT-licensed Android template that gives you a multi-module Clean Architecture project with MVVM, Jetpack Compose, Hilt, Retrofit and a full quality toolchain instead of an empty build file. The trade is that it is opinionated down to the Gradle convention plugins, and it still demonstrates two reactive stacks at once.

**Drjacky/MVVMTemplate** — An Android Template with MVVM and Clean Architecture - including a Compose version(default branch)

- Repository: https://github.com/Drjacky/MVVMTemplate
- Stars: 896 · Forks: 132
- Language: Kotlin
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/drjacky-mvvmtemplate

## The problem: the first day of an Android project

A new Android project starts with a decision problem disguised as a build file. Which architecture, which reactive approach, which dependency injection, how many modules, and where does the code that talks to the network live. Most teams settle this by copying the last project, which means inheriting its accumulated mistakes along with its accumulated structure.

MVVMTemplate is a template that answers the questions in advance. The project description calls it a simple Android template that lets you create an Android project quickly, and the repository is the answer to a lot of small questions settled once and repeated: Kotlin, Jetpack Compose with Material 3, a multi-module Clean Architecture layout, Hilt for injection, Retrofit and OkHttp for the network, kotlinx-serialization for JSON, Paging 3 for lists, and DataStore for preferences.

The versions are pinned in the badges, which is the clearest statement of intent in the repository: Kotlin 2.3.21, Android Gradle Plugin 9.2.0, minimum SDK 24 and target SDK 37. A template that pins its toolchain is a template you can trust to build, and one that leaves it loose is a template you will spend a day fixing.

The audience is a developer or small team starting an Android application, and the intended workflow is the Use this template button on the repository, which creates a new repository from it. There is also a BasicComposeActivityPlugin repository referenced for a basic, starter version of the same architecture, which is the more sensible choice for a single-screen app or a spike.

The licence is MIT, the repository is not archived, and the last push was on 2026-05-03, so the template is maintained at intervals rather than continuously.

## The module layout: app, build-logic, core and feature

The architecture is visible in the directory tree, and the project publishes it:

```text
MVVMTemplate/
├── app/                     # Application module (MainActivity, Navigation, DI wiring)
├── build-logic/             # Convention plugins (shared build configuration)
├── core/
│   ├── common/              # Shared base classes, utilities, DataStore
│   ├── data/                # Repository implementations, data sources, API models
│   ├── domain/              # Use cases, domain models, repository interfaces
│   ├── network/             # Retrofit setup, OkHttp configuration, network response handling
│   ├── testing/             # Shared test utilities (TestDispatcherRule, fakes, test data)
│   └── ui/                  # Shared Compose UI components, theming, screen states
└── feature/
    └── products/            # Products feature (list, detail, choose screens)
```

The shape is the standard Clean Architecture split, with the dependency rule made structural rather than aspirational. The domain module holds use cases, domain models and repository interfaces and knows nothing about Android, the data module holds the repository implementations and the data sources, and the network module holds the Retrofit and OkHttp configuration. The core:ui module holds shared Compose components, theming and screen states, so a feature module contains screens rather than a copy of the design system.

Two entries are worth attention. The build-logic directory holds convention plugins, which is how the shared build configuration is factored out instead of copy-pasted into every module. And core/testing exists as a module, so the fake data and the test dispatcher rule are shared rather than duplicated.

The feature directory holds a single products feature with list, detail and choose screens. That is the template's argument in miniature: one feature is enough to show the pattern, and the rest are copies of it.

## Two reactive stacks in one app, chosen at runtime

The most surprising thing about this template is that it demonstrates both RxJava and Coroutines side by side, and lets the user pick which reactive approach to explore at runtime through a choose screen.

That is unusual, and it is deliberate. The documentation says the app demonstrates both, and the topics list includes rxjava2, coroutines, coroutines-android and flow. In practice, the Coroutines path is the primary one: the core feature list pairs Coroutines and Flow with StateFlow for UI state, and the tests use the coroutines test library. RxJava 3 is present as a comparison, and Paging 3 is configured with both a Coroutine and an RxJava data source.

The trade-off is worth naming plainly. A template that carries two reactive stacks is a template where you will delete one of them, and the deletion is a real edit rather than a config change. The benefit is that a developer who is coming from RxJava, or who is evaluating whether to move, can see the same feature implemented both ways in a running app instead of reading migration guides.

The state model is the modern one. StateFlow for UI state means the screen has a single observable stream of screen state, which is the pattern that survives rotation, process death and testing with a test dispatcher. The choose screen that lets you switch stacks is where that comparison becomes concrete.

## The feature list is a statement of opinion

The template's feature list reads as a set of decisions rather than a checklist, and it is worth taking the positions seriously because they are the positions of a working app.

On the UI side, it is Jetpack Compose throughout, with Material 3 and Material You dynamic colour, light and dark themes and edge to edge support. Navigation is Navigation 3 with type-safe Compose navigation using NavKey and NavDisplay, which is the newer approach that replaces route strings with typed keys. Media handling is Lottie for vector animation, Coil for image loading and Palette for dynamic card colouring from image palettes.

On the data side, Retrofit 3 is the HTTP client, OkHttp is the network interceptor, and kotlinx-serialization handles JSON rather than a reflection based library. There is a custom NetworkResponse sealed class for structured API response handling, which is the piece that stops every call site from re-implementing the same error branching. Paging 3 handles pagination, and DataStore handles preferences storage.

On the build side, the version catalog in libs.versions.toml centralises dependency versions, KSP is used for annotation processing, and a compose_compiler_config.conf holds the Compose stability configuration with compiler metrics and reports.

The result is a template that is opinionated in the places where opinion is useful, and the opinion is consistently the modern one. If your team has already settled these questions differently, the template is still a good reference for the parts you have not thought about, and a bad starting point for the parts you have.

## The quality toolchain: Detekt, StrictMode, LeakCanary and five more

The tooling section is where a template earns its keep, because these are the things that are painful to add later.

Static analysis runs through Detekt with the Compose rules enabled, and there is a separate Gradle Doctor integration for build health. Dependency insight comes from the dependency analysis Android Gradle plugin, and Sonatype Scan provides dependency security scanning.

At runtime, StrictMode is configured with the detectAll() thread policy and leaked object detection, LeakCanary handles memory leak detection, Chucker gives you an HTTP inspector inside the app, and Timber handles logging.

The CI badges show the whole chain: a Pre Merge Checks workflow, an Android CI workflow, a SonarCloud quality gate, FOSSA for licence and dependency scanning, and a CodeScene code health badge.

One detail in the repository is worth repeating because it is a common trap. There is a commented out Snyk badge with a note explaining that Snyk does not support Kotlin DSL. So the template handles the security scanning question with Sonatype Scan rather than Snyk, for a reason that has to do with the build script language rather than with policy. If you copy this template and move to a Groovy build, that constraint disappears.

The practical advice for anyone using the template is to run these tools before you write features, not after. A codebase that starts with Detekt and a dependency analysis plugin stays clean; one that adopts them in month three does not.

## Testing with fakes, and a shared core:testing module

The testing section follows the fakes over mocks pattern, and the project links the reasoning behind it. Unit tests use Truth for fluent assertions, Turbine for testing flows, and the coroutines test library with a TestDispatcherRule for deterministic coroutine tests. The shared core:testing module holds reusable fakes and test data, and the tree comment names the TestDispatcherRule, the fakes and the test data as its contents.

The pattern choice matters. Mocks assert that the code called a collaborator in a particular way, which couples a test to the implementation. Fakes give you a working implementation of a dependency, so a test exercises real behaviour and survives a refactor of the code under test. For a template that ships a repository layer behind repository interfaces, fakes are the natural fit, because a fake repository is trivial to write against an interface.

Turbine is the detail that shows the template targets flows specifically. Testing a Flow by collecting it in a test and asserting on a list of emissions is awkward without a helper, and Turbine is the helper for that.

The TestDispatcherRule in the shared module is the other half. Coroutines tests fail or hang when the dispatcher is not controlled, and a rule in a shared module means every test module uses the same one.

## Using the template, and what to check before you build on it

Getting started is one click. The Use this template button creates a new repository from this one, which is the standard GitHub template flow and gives you a project you own with its own history.

Two details deserve attention before you start. The first is the branch. The default branch of this repository is feature/compose, not master, and the repository description says the Compose version is the default branch, so the Compose setup is the one you get. The legacy README links in the repository point at the master branch for the logo, which is a small sign that master and the Compose branch have drifted apart in terms of documentation.

The second is the maintenance state. The repository has no GitHub releases, so there is no tagged version to pin, and the last push was on 2026-05-03, roughly five months before this article. The toolchain versions in the badges are therefore a snapshot, and the dependencies they pin will age. Expect to update Kotlin, the Android Gradle Plugin and the Compose libraries as part of your first week, and read CHANGELOG and UPGRADE notes for those libraries rather than assuming the template's versions still build.

The last thing to weigh is scope. This is not a minimal template. The module graph, the convention plugins, the two reactive stacks, the quality toolchain and the shared test module together make it a substantial starting point, and a single screen application does not need most of it. If that is your project, the BasicComposeActivityPlugin repository referenced in the documentation is the one to start from, and you can lift the quality tooling across later.

The licence is MIT, so there is no obligation to publish anything you derive from it, and the accessibility details are a good sign of the template's level of care: semantic properties for TalkBack, a 48dp minimum touch target, string resources with translator context comments, and non-transitive R classes for resource scoping.

## Conclusion

Adopt MVVMTemplate if you want a new Android project to start from a working multi-module Clean Architecture setup with Compose, Hilt and the quality tooling already wired. Do not adopt it if you need a minimal starting point, because the module graph and the toolchain are substantial and the project itself points to a lighter option for that. Before you rely on it, check the default branch, which is feature/compose rather than master, and note that the repository has no GitHub releases and that the last push was on 2026-05-03, so you should expect to update the dependency versions yourself.

## FAQ

### How do I start an Android project from MVVMTemplate?

Use the Use this template button on the repository to create a new repository from it. The documentation also points to the BasicComposeActivityPlugin repository for a basic, starter version of the same architecture with less ceremony.

### Which branch of MVVMTemplate is the Compose version?

The default branch is feature/compose, and the project description states that the Compose version is the default branch. Some links in the repository still point at master, so the documentation on the two branches is not fully in step.

### Does MVVMTemplate use RxJava or Coroutines?

It demonstrates both side by side, and a choose screen lets you pick which reactive approach to explore at runtime. Coroutines and Flow with StateFlow carry the primary path, RxJava 3 is included for comparison, and Paging 3 is configured with both a Coroutine and an RxJava data source.

### What testing tools does MVVMTemplate set up?

Unit tests follow the fakes over mocks pattern, with Truth for assertions, Turbine for flow testing and the coroutines test library with a TestDispatcherRule for deterministic tests. A shared core:testing module holds the reusable fakes, the test dispatcher rule and the test data.

### What licence is MVVMTemplate released under?

MIT, with the LICENSE file at the root of the repository. The repository has no GitHub releases, and the last push was on 2026-05-03, so the pinned Kotlin 2.3.21 and AGP 9.2.0 versions are a snapshot to update rather than a fixed baseline.

## Sources

- [Drjacky/MVVMTemplate on GitHub](https://github.com/Drjacky/MVVMTemplate)
- [Issues](https://github.com/Drjacky/MVVMTemplate/issues)
- [License: MIT](https://github.com/Drjacky/MVVMTemplate/blob/feature/compose/LICENSE)
- [README](https://github.com/Drjacky/MVVMTemplate/blob/feature/compose/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/drjacky-mvvmtemplate
