Kotlin is one of my favorite languages for logic and you rather agree with me that this lang has changed the mobile world and also the roadmaps of many other languages, like Java, Dart, etc. Kotlin is safe, concise, expressive, and can be also easily mixed with other JVM langs. Together with Arrow, they provide a very good functional solution to create more intuitive and reliable code. Kotlin starting to be also popular on the backend because Spring and Spring Boot provide support for it and there is also a lightweight Kotlin based framework called Ktor.
For the frontend UI part, we have declarative UI which can reduce a lot of boilerplate code and drastically reduce coupling comparing to an imperative approach well-known from current iOS and Android development. Both systems have a UI toolkit which was designed in 2007/2008 when the systems were born. As we know mobile apps during that time were rather small and limited, so UI has not needed a lot of performance optimization and functionalities which are required to create complex layouts. Right now we have new tools for our user interface like SwiftUI for iOS and Jetpack Compose for Android. Comparing to the current imperative approach, a declarative one can reduce coupling and provide less boilerplate code.
You know, imperative programming is like how you do something,
and declarative programming is more like what you do, or something.
In Declarative UIs like Jetpack Compose the user interacted with a UI element, causing an event to be triggered. The app logic responds to the event, then the composable functions are automatically called again with new parameters, if necessary. In that case or when new data are available, the app logic provides data to the top-level composable function. That function uses the data to describe the UI by calling UI elements and passes the appropriate data to those elements, and on down the hierarchy.
And based on that we can say that:
Declarative UIs build their user interface to reflect the current data/state of your app
Declarative UI benefits:
- More focus on code: implement behavior and ignore stuff that is not relevant
- Reusable: declarative UIs can be used with a different code (logic) and code can use a different UI and still work
- Separation of concerns: (UI no longer affects the code and they can be designed independently (still need a common interface to be agreed)
Nowadays, to have the best native support, companies build separate apps for each platform (Android, iOS, Web, and Desktop) To limit the amount of code being replicated for each platform, instead of shared code, most apps tend to be ‘thin client’ and whole business logic is moved to server-side and it is shared via webservices. This usually does not allow the user to use the app in offline mode and it also sometimes provides limitations.
On the other hand, we have cross-platform or hybrid solutions like Flutter, React Native, Xamarin, Ionic. These technologies allow us to create apps with almost one codebase, but usually, some edge cases or new OS features cannot be easily covered. This causes that still pure native development is the most popular but also not a cheap approach.
A New hope
To solve the issue of cross-platform limitations we can consider a new Declarative UI approach and Kotlin Multiplatform as a solution. This can be the future of (mobile) systems programming. This gives us the possibility to build apps for all platforms, which share 75–90% of the codebase and have the latest native UI/UX in use. With Declarative UIs we can reduce dedicated code to 10–25% of the whole code which is running on a specific platform. This will allow the developer team to spend more time on unit and integration tests of business logic and provide automated verification for the core of the app which is your business logic.
This will increase the quality of your product because the logic will be shared and well tested for all platforms.
We can create separate UI using a declarative framework per each platform:
- Android: Jetpack Compose
- iOS: SwiftIU
- Web: React
- Desktop: Compose for Desktop
All data changes(states) and events we can easily manage by shared Kotlin
Multiplatform ViewModel in MVVM architecture. Decupling of the declarative way allows us to create SOLID, clean, easy to maintain code. Under ViewModel we can have a repository pattern and data management system also written in shared Kotlin Multiplatform code.
Is it production-ready?
Kotlin Multiplatform (Mobile) is in the Alpha stage now. It is expected to reach a Beta stage in Q2 2021 and we can expect a stable version also this year. Despite the alpha state, the technology is used in production by many developers. Our experience also confirms that the risk is quite low in the case of KMM. Kotlin also provides wrappers for React.js, which allows us to use Kotlin/React as our DeclarativeUI layer on the Web
Jetpack Compose should be production-ready in 2021 based on data mentioned by Google. For now, it is still in Alpha and rather cannot be used on productions for advanced apps because of some gaps in functionalities. Good from the Android ecosystem perspective is that JetpackCompose is supported by any device with Android 5 (API 21) and later. Unlike JetpackCompose, SwiftUI is unfortunately tied to the iOS framework for updates. New SwiftUI APIs will not be backward compatible. However, considering that all devices supporting iOS13 are also supporting iOS14 we can use the latest version of it. SwiftUI is also mandatory for the implementation of some iOS features like Widgets.
We can expect that Google and Apple will keep focusing on their new Declarative UI solutions and this will be the future of Mobile programming. Together with Kotlin Multiplatform, we can create a reliable, healthy, and modern solution for Mobile and Web development. How to do this with code examples I will show you in the next part of this article, so please stay tuned!