reactive-mvvm-android: a coroutines and data binding take on MVVM
My way to MVVM using KotlinX Coroutines and Android data-binding
At a glance
- What is it?
- reactive-mvvm-android is an Apache-2.0 Kotlin sample that wires MVVM with the architecture components, KotlinX Coroutines for async work, LiveData and data binding for the view layer, and Room for storage, with Koin for injection and Kotest, JUnit 5 and Turbine for tests. It suits a developer studying a layered Android architecture, and it is a sample app with a 2020 release line.
- Who is it for?
- reactive-mvvm-android fits a developer who wants one readable vertical slice of an Android app built around coroutines and Flow with data binding, since the whole project is small enough to read in an afternoon and the dependency set is a sensible 2020-era stack.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 83 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A sample app, not a framework
The README is short, and it opens by naming the intent: my way to MVVM using KotlinX Coroutines with Android data binding. The word my way is the important qualifier. This is one developer's worked example of an architecture, published as an app you can read, not a library you depend on.
The summary section sets out the design in five lines. MVVM using the architecture components to separate the Android framework from the domain logic with a clean architecture, following the linked Uncle Bob article. Android data binding with LiveData to glue the ViewModel and Android together. Asynchronous communications implemented with KotlinX Coroutines. A REST API from ComicVine, the public comics database API. And data stored using Room.
That last pair of choices defines what the sample actually demonstrates. ComicVine is a small, well documented, unauthenticated-ish public API with a JSON schema, which makes it a good vehicle for showing a data layer without the ceremony of a real backend. Room then persists what came back, so the app shows the full round trip: network, database, and a view observing both.
The audience is a developer learning or reviewing Android architecture. The value is in the shape of the code, not in the feature set, and the app is a comic browser, so nothing about it is a template for a production data layer.
The author is Fernando Franco Giráldez, and the licence is Apache 2.0, with the copyright line dated 2019 and the full licence text in the repository.
The dependency list, and what each choice signals
The Dependencies section is the most concrete part of the README, and reading it as a set of decisions is more useful than reading it as a shopping list.
* livedata
* room
* viewmodel
* kotlinx coroutines
* floating search
* okhttp
* retrofit
* koin
* picassoThe architecture components group is the AndroidX set: LiveData as the observable holder that the data binding layer reads, Room as the persistence layer, and ViewModel as the presentation holder that survives configuration changes. Coroutines and Flow carry the asynchronous work.
The networking pair is OkHttp with Retrofit, which is the standard combination of a client and a declarative interface layer. Picasso handles image loading. Floating search is a UI component library for a search bar, which tells you the app is a browsing UI rather than a form-heavy one. Koin does dependency injection, and that choice is a signal in itself, since Koin is the lightweight, code-based alternative to the heavier annotation-processor approaches, and it fits a sample that should be readable without a build-time codegen story.
Two things are notably absent. There is no dependency injection framework from the annotation-processing school and no mocking library for the network layer, and neither absence is explained in the README. And there is no mention of an image loading library beyond Picasso, so there is no Glide or Coil in this stack.
The repository layout backs the same picture. There is an app/ module holding the application code, a dependencies.gradle file that presumably pins the versions, a root build.gradle, a settings.gradle, a gradle wrapper with gradlew and gradlew.bat, gradle.properties, a renovate.json for automated dependency updates, and a small images/ directory for the README's social links.
A test stack with Turbine in the middle
The Testing section lists three libraries, and the combination is more interesting than any single entry.
Kotest is the assertion and spec framework, so the tests are written in a Kotlin-idiomatic style rather than the class-per-test-classic JUnit 4 style. Android JUnit 5 is the runner, using the mannodermaus project, which provides the JUnit 5 platform on Android, since JUnit 5 does not run on Android out of the box and needs a specific integration to work there. Turbine is the third piece, and it is the one that does the interesting work.
Turbine is a library for testing flows. It takes a Flow and gives you a test API for collecting its emissions, so a test can assert the sequence of values a flow produced and then cancel it, without writing the collector boilerplate by hand or losing the emissions to a race.
That matters for this project specifically, because the architecture is built on coroutines and Flow. If the repository exposes its data as flows and the ViewModel consumes them with the reactive programming style the topic list describes, then a large part of the logic lives in flows, and a test framework that can assert on flow emissions is not a nicety, it is what makes the reactive part testable at all.
The TODO list in the README also shows the author's own view of the state of testing. Better UI, with Material Design concepts and so on, is still open, while Add unit tests, always fail on that, is struck through and marked as done. So the testing was an acknowledged weak point that the author closed, and the 2.7.1 release is titled Cover by tests, which fits.
The topic tags on the repository reinforce the picture: coroutines-flow, kotlin-flow, functional-reactive-programming, livedata, room, viewmodel, koin and arrow-kt, the last of which suggests a functional error-handling approach in the domain layer.
The 3.0 release: rx-java out, kotlinx-coroutines in
The release history is short and the important entry is the last one. Version 3.0.0 is titled rx-java and to kotlinx-coroutines, released on 2020-10-02, and it is a major version bump for a library that already had a 2.x line with many releases behind it.
The 3.0 change is the single most useful thing this repository demonstrates to a modern reader. Before 3.0, the asynchronous layer was RxJava. After it, it is KotlinX Coroutines. That is a migration of the whole reactive surface of the app, from an RxJava-based view model layer with LiveData bridging, to coroutines and Flow, with the flows consumed by the data binding layer.
Two prior releases show the rhythm. 2.8.0, from 2020-09-30, is titled keep dependencies up to date, which is a maintenance release in the ordinary sense. And 2.7.1, from 2019-07-08, is the tests release.
The sequence tells a coherent story: the author shipped a sample on RxJava, spent a year or so adding tests and updating dependencies, and then made the call to move the async layer to coroutines, which is the direction the platform itself moved in and where the whole ecosystem of tooling, testing support and documentation now lives.
If you are reading this sample in order to learn a current approach to reactive Android, the 3.0 line is the relevant one. The 2.x code is of historical interest mostly as a demonstration of what the migration looked like, and the release titles make the switch plain.
What the README leaves undocumented
There is a real gap here, and it is worth naming rather than glossing over.
The README does not describe the module structure in any detail. There is an app/ directory and a dependencies.gradle, but nothing states how many Gradle modules exist, what the domain, data and presentation packages are called, or how the clean architecture separation the summary claims is actually arranged on disk. The summary also has a typo in it, describing the architecture components as the mechanism to separate the Android framework from the domain logic, when the separation is what the components are used for.
Nor does it say how the ComicVine API is consumed. There is no snippet, no base URL, no endpoint list, no mention of pagination, caching strategy or how the Room entities relate to the API responses.
The README does not document how to build or run the project. There is no installation section, no mention of the required Android SDK version, no Gradle command for assembling the debug build, and no instructions for the configuration the ComicVine client needs, which is likely a base URL and an API key supplied as a build config value.
None of this is unusual for a sample repository README, and the code is the documentation. But an evaluator should read it as such: the value here is the working code and the dependency choices, not the prose. A team that wants to adopt this as a starting point needs to read the app module, check the pinned versions, and supply their own API configuration and their own domain logic, because none of the interesting parts of a production app are in this repository.
The build files themselves are the only technical documentation in the project, and they are worth opening before anything else.
Where reactive-mvvm-android is the wrong starting point
The first limitation is the age of the stack. The last tagged release is 3.0.0 from 2020-10-02, and the last push was on 2026-08-01, so the tree is being touched but no release has been published in nearly six years. More importantly, the architectural centre of gravity has moved. The sample is built on data binding and LiveData, which the platform documentation has since steered away from in favour of Compose, and the pinned versions in dependencies.gradle are from a period before the current Android Gradle Plugin and Kotlin toolchain conventions settled.
Adopting the structure of this sample today means adopting a 2020 approach deliberately, which is defensible in a codebase that already uses data binding and needs to introduce coroutines, and is a strange choice for a new project.
The second limitation is that it is a sample of a layer, not of an application. The repository topics list arrow-kt, which points to a typed error model in the domain layer, and the README mentions clean architecture. But there is no real domain here, no repository abstraction over a network source, no use case interactors, no paging, no authentication and no offline conflict handling. A comics browser against a public API does not have any of the problems that make architecture hard, so the code will not show you how this architecture behaves when it gets difficult.
The alternative worth comparing is not another sample, it is a first-party path. The official Android architecture guide now documents a recommended structure that uses a data layer with repositories exposing flows, a domain layer where the business logic lives, and a UI layer built with Compose, and the platform ships Unidirectional Data Flow as the recommended pattern for state. The difference in approach is the direction of influence. This repository shows one author's 2020 implementation of a good idea, while the platform guide shows the current consensus, maintained by the people who build the framework, and it will be current where this repository is not.
The case for using this repository is narrower and still real. If you are looking for a compact, readable example of how coroutines and Flow drive LiveData through data binding, with a test suite that uses Turbine to assert on flow emissions, and you want to see that pattern in one app rather than in documentation, this is a good thing to read. Copy the shape, not the versions.
Editorial conclusion
reactive-mvvm-android fits a developer who wants one readable vertical slice of an Android app built around coroutines and Flow with data binding, since the whole project is small enough to read in an afternoon and the dependency set is a sensible 2020-era stack. It is the wrong choice as a production foundation, because the last tagged release is 3.0.0 from 2020-10-02 and the last push was on 2026-08-01, and because a sample that talks to a public comics API is not a template for a data layer with real requirements. Before copying from it, read the app/ module to see how the layers actually talk to each other, and check the versions in dependencies.gradle against what your current toolchain supports, since the LiveData and data binding approach it demonstrates has since been joined by Compose in the platform's own guidance.
Frequently asked questions
What architecture does reactive-mvvm-android demonstrate?
MVVM using the Android architecture components, with data binding and LiveData gluing the ViewModel to Android, KotlinX Coroutines for asynchronous communication, a clean architecture separation of the domain logic, Room for storage and a REST API from ComicVine.
Which libraries does reactive-mvvm-android use?
The architecture components LiveData, Room and ViewModel, kotlinx coroutines, floating search, okhttp, retrofit, koin and picasso, with Kotest, Android JUnit 5 and Turbine for testing.
What changed in version 3.0.0 of reactive-mvvm-android?
The 3.0.0 release is titled as the move from rx-java to kotlinx-coroutines, published on 2020-10-02, and it replaced the RxJava based asynchronous layer with KotlinX Coroutines and Flow in the 2.x line that preceded it.
How does reactive-mvvm-android test its reactive code?
With Kotest as the assertion framework, Android JUnit 5 as the runner using the mannodermaus project, and Turbine for testing flows, which provides a test API for asserting on flow emissions and cancelling the flow.
What licence is reactive-mvvm-android released under?
The project is licensed under the Apache License, Version 2.0, with the copyright line held by Fernando Franco Giráldez and the licence text in the repository. The last push was on 2026-08-01 and the latest tagged release is 3.0.0 from 2020-10-02.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ffgiraldez-reactive-mvvm-android)Was this useful?