Android / August 8, 2022 / 4 mins read / By Atri Tripathi

Jetpack Compose and the conundrum of selecting a suitable architecture

Jetpack Compose is a modern and declarative UI framework developed by Google for Android to effectually replace the older View-based imperative UI system, which demands an excessive amount of ceremonial setup to render even simple UI elements on the screen. The promise of Jetpack Compose lies in its ability to simplify UI development by allowing us to define, more or less, “what” rather than “how” it is to be rendered — declarative over imperative.

At SuperShare, we’re rewriting our Android app natively from scratch using the latest tech, libraries, design patterns, feature sets and frameworks that Google offers. And one of the primary decisions we had to take at the onset was selecting a suitable mobile software architecture — MVVM or MVI.

The other famous architectures like MVC, MVP and Mobius (close contender) had other blatant and severe shortcomings, which we were already aware of; hence they weren’t in our consideration from the beginning. We were aware that our decision would have an impact on the application for its entire lifetime, which also, in a way, justified our predicament. We had to tread carefully with this decision and thoroughly weigh our biases on one or the other architecture.

Moreover, our UI layer had to be written entirely using Jetpack Compose, and the tricky thing with it is that, unlike the View system, Jetpack Compose is built and works using the concept of State-Machine. It operates and relies on a delicate and measured dance between the State changes and the Events that trigger them. In simpler words, we had to rethink, adjust and accommodate our way of writing UI code from a mutation-friendly, less contractual and more flexible world to a more purist’s immutability, pure functions, and “state-flows-down, events-flow-up” way of seeing the world.

The following sections delineate our precise observation of the characteristic strengths and weaknesses of both the architectures and then our final verdict.

MVVM

MVVM Architecture

  • MVVM stands for Model-View-ViewModel architecture.

  • It was adopted by Google as the standard architecture for developing Android apps several years ago, and they still stand by it.

  • It’s a development on the MVP pattern, where it replaces the Interface and its modifications between the View and Presenter with a Pub-Sub/Observer pattern between the View and ViewModel.

  • Its strongest suit offering is the lifecycle-aware ViewModel and the ability to have granular control over each UI component using Compose friendly state-holder variables, preferably in the ViewModels, that is decoupled from the screen’s state.

MVI

MVI Architecture

  • MVI stands for Model-View-Intent architecture.

  • It is a reactive architecture that was developed in public and had strong backing from the developer community.

  • It was developed as an alternative for Android taking inspiration from Redux, a state-machined-based JavaScript library for the Web.

  • Its strongest suit is that it abides by purist’s principles of writing code, wherein entities and objects are immutable, and therefore they become good representatives of State, and any Event/Intent that wants to change the State does so, not by directly changing the value, but by creating a copy of the object using special functions called Reducers. This keeps the code resilient, thread-safe and testable.

Verdict

We chose MVVM.

Now, I agree that on the envelope, reading the above bullet points, it may seem quite evident that MVI should be a clear yes and the way to go, given the fact that it clearly mimics Jetpack Compose in its state-machine-based operational behaviour. And to be honest, we were very split and closely considering this point too.

But what made MVVM win the bid had to do with two points:

  1. MVVM still has and probably in the near future will continue to have a strong backing as the standard architecture for Android app development from Google.

  2. The fact that MVI was developed for Android as inspiration from Redux for JavaScript seemed an overkill, in lieu of the fact that although it might’ve made sense in JavaScript to have proper state management by funnelling your state changes through central Reducer functions because the language itself suffers from a lack of strict typing system, it didn’t really make sense for us with Java/Kotlin, because they do have strict typing system, and therefore a centralised funnelling may or may not have been good to have, but it was never really a necessity.

The last thing to be mentioned here is that some developers have tried using a mix of both the architectures — where the central structural scaffolding is provided by MVVM, and only the cosmetic layer between the ViewModel and the View with Jetpack Compose is taken care of by a simplified and neutered down version of MVI’s extensive rigmarole.

Only time will tell how it all really plays out as Jetpack Compose matures.