Should you have any questions or ideas please welcome to the Slack channel: #mvikotlin
⚡⚡⚡ Why is this repository a fork?
Having spent 5 years working on a variety of projects for Badoo/Bumble, I’m now off to another adventure. As part of that transition I was asked to transfer this repository to Badoo GitHub account.
Now I continue my work on this project as a fork.
There should be no breaking changes related to this transfer. Most of the external links should not be broken. The repository link is also the same: arkivanov/MVIKotlin. Please file an issue in this repository, if you think something is broken or does not work properly.
Here is what is mostly affected by the transfer:
- All the stars were transferred
- Search in the code will not work as long as this repository has less stars than the parent (your help is needed!)
- All the Issues and Discussions were transferred as well. I will do all my best to fill the gap here.
- All pull requests with all the comment history are also gone.
I will continue doing all my best for this project and for the community! Business as usual!
What is MVI
MVI stands for Model-View-Intent. It is an architectural pattern that utilizes unidirectional data flow. The data circulates between
View only in one direction – from
View and from
What is MVIKotlin
MVIKotlin is a Kotlin Multiplatform framework that provides a way of (not only) writing shared code using MVI pattern. It also includes powerful debug tools like logging and time travel. The main functionality of the framework does not depend on any reactive nor coroutines library. Extensions for Reaktive and for Coroutines libraries are provided as separate modules.
Responsibilities and architecture
MVIKotlin does not bring or enforce any particular architecture. There is one primary responsibility of the library:
- To provide a single source of truth for
State. The scope is not defined, it can be a whole app, a screen, a feature, or a part of a feature.
There are also two optional responsibilities, which the library can take care of for you:
- To provide an abstraction for UI with efficient updates (diffing).
- To provide lifecycle aware connections (bindings) between inputs and outputs.
Everything else is out of scope of the library, there are no definitions for “screens”, “features”, “modules”, etc. Also, no particular reactive framework is enforced/exposed. This gives a lot of flexibility:
- MVIKotlin can be introduced incrementally (e.g. you can start using it in a small feature and then expand gradually);
- You can use/experiment with different architectures, approaches and/or libraries for navigation, UI, modularization, etc;
- Use whatever reactive framework you like or don’t use it at all.
If you are using declarative UI frameworks (like Jetpack Compose, Multiplatform Compose by JetBrains, SwiftUI, React, etc.), then consider using Decompose for architecture. MVIKotlin plays nicely with Decompose – a very good example is compose-jb/todoapp.
Also one of the architecture approaches can be found in the samples.
Recommended minimum Gradle version is 5.3. Please read first the documentation about metadata publishing mode.
There are a number of modules published to Maven Central:
mvikotlin– core interfaces and functionality (multiplatform)
mvikotlin-main– the main module with the default
mvikotlin-logging– logging functionality (mutiplatform)
mvikotlin-timetravel– time travel feature (mutiplatform)
mvikotlin-extensions-reaktive– extensions set for Reaktive library (multiplatform)
mvikotlin-extensions-coroutines– extensions set for coroutines (multiplatform)
(deprecated, see the documentation)
InstanceKeeperAPI for state preservation and objects retaining
rx– a tiny module with abstractions over rx and coroutines (multiplatform)
Add required modules to your module`s build.gradle file:
IDEA Live Templates
To speed up the creation of new Stores, you can use the following IDEA Live Templates.
- Does not depend on any reactive library or coroutines
- Extensions for Reaktive library
- Extensions for Coroutines
- Multithreading friendly (freezable in Kotlin Native if needed)
- Lifecycle-aware connections (bindins) between inputs and outputs
- Logging functionality with customizable logger and formatter
- Time travel feature:
- Multiplatform for all supported targets
- Plug-and-play UI for Android
- Plug-and-play UI for iOS (copy-paste from the sample app)
- Export/import events for Android
- IntelliJ IDEA and Android Studio plugin for Android apps
- Desktop client application for Android, Java and native Apple (iOS, watchOS, tvOS, macOS) apps
- Chrome DevTools extension for Web browser apps
The sample project is a todo list with details view.
- Shared module using Reaktive is here
- Shared module using coroutines is here
- Sample Android application with both Reaktive and coroutines implementations, plus logging and time travel is here
- Sample iOS application with Reaktive implementation only, plus logging and time travel is here