Choosing the best cross-platform framework for sharing code between iOS and Android.

Tomasz Babiuk
16 min readOct 23, 2018

--

Do you want to share your code between Android and iOS? Don’t know which framework fits best? See my comparison of Xamarin, React native, Flutter and Kotlin/Native backed by few years of playing on cross-development field.

Photo by Benjamin Wong on Unsplash

Most popular mobile apps need to be written twice: first time in Java (or Kotlin) for Android and second time in ObjectiveC/Swift for iOS. In most cases the code is duplicated and developer effort is doubled. The more code you need to produce, the more bugs you may expect so testing efforts are doubled as well.

Sharing code between iOS and Android is good for everybody. Developers may focus on business requirements instead of interoperability tasks. Clients are getting product for a lower price in much shorter time. Finally, your end users are getting better tested product. That’s the theory.

TL;DR; I know it’s a long time read… you can find the rating table (and the winner of course) at the end of this story.

Why another cross-platform comparison article?

I’m an Android developer with strong .NET background (I wrote some Xamarin apps in the past). I decided to write this article when I got my last “You’ve been found by this skills…” email from LinkedIn. It appears that my Xamarin skills are more valuable than Android ones. The math was simple: 23 hits for Xamarin vs 5 for Android. I was surprised at the beginning… Xamarin is hard to work with so it’s obvious that it’s more difficult to find somebody who knows it. There’s a lot of free Android developers available.

Another surprise was when I was briefly looking at remote jobs in mobile. For 20 job ads there were only 2 for Android, 6 for Swift and 12 for Xamarin. Is this so hard to find somebody for Xamarin? Or is this technology so cool that demand is rising? Are there any vital alternatives for this tech? I’ll try to answer to all of this questions.

Comparing Xamarin, Flutter, React native and Kotlin/Native

I was using Xamarin since 2012. I remember times when it was a full paid framework with no relation to Microsoft. Xamarin was my key to Android world as I was a .NET developer before. I wrote few commercial applications using this tech.

When it comes to React/Native, Flutter and Kotlin/Native: I got the chance to create some proof of concepts to test them out. That was more than enough to do this comparison.

How to rate best cross-platform framework for mobile?

I choose 14 criteria to rate the frameworks. My goal was to touch every aspect of cross-platform development starting from required skills, knowledge aspects, tooling, maintenance and performance. I even tried to find the best answers to question “how hard it is to find developer on the market” for every cross-platform solution. So let’s start!

Rating points means:

1 — poor, actually not so bad but nothing extra comparing to others

2 — good and at least better than competition

3 — excellent, definitely better than others

Criteria 1: What skills do you need to know to build business logic (entry level)?

Xamarin (1 point) — You need to know C# and most popular .NET libraries for things like dependency injection, data binding, networking, etc.

The problem is that you are not able to use everything from .NET world but only limited set of cross-platform libraries that are written in .NET (previously called Portable Class Libraries).

Don’t expect C# knowledge will let you roll on Android and iOS. You still need to know Java or Kotlin and Swift to read the docs. Sooner or later you also need to write more advanced part of interoping code and deep knowledge of Android SDK and iOS framework are required.

Flutter (1 point) — Same as in Xamarin but except of C# and .NET you’re dealing with Dart. You’ll also need to get familiar with Dart specific libraries for everything. Forget everything you know and dive in here: https://pub.dartlang.org/packages?q=dependency%3Aflutter&page=1.
It’s also important to know how to use Dart performance tricks like isolates.

Same as in Xamarin… you still need to know Kotlin + Android SDK + Swift + iOS SDK for more advanced development.

React native (1 point) — You need to know JavaScript (ES6) and it’s relatives (npm, JSX and all the stuff). I won’t lie if I tell that there’s a lot of stuff to learn.

Same as in Xamarin and Flutter… you still need to know Kotlin + Android SDK + Swift + iOS SDK for more advanced development.

Kotlin/Native (2 points) — You need to know Kotlin + Android SDK + Swift + iOS SDK. There’s no need to learn another layer or language that is not present on regular mobile development (C#, XAML, JXL, Dart, ES 6, etc.)

It’s easy to convert Java code to Kotlin. Porting existing Java code directly to Kotlin/Native is extremely simple. Kotlin/Native is also a part of Kotlin 1.3.

Skill set criteria is the most controversial. The final judgement depends on what languages you know. If you’re coming from .NET world it would be easier for you to get better traction in Xamarin. If you’re coming from the web — React native is the only choice, etc.

The extra point for Kotlin/Native is for not introducing another language that’s not being used in mobile development (modern Android developers are using Kotlin already).

Criteria 2: What skills do you need to know to build UI interface?

Xamarin (2 points) — In Xamarin you have two options. You can use the bridge between .NET and Java/Swift and write the UI as you were regular Android/Swift developer (except the syntax is C#). You still need to know all the rules on how interface has to be built on specific platform.

You can also use Xamarin Forms and XAML markup to share the view tree across iOS and Android. In this approach XAML tree is translated to platform specific view tree. Theoretically you don’t need to build the views twice but the problem is that sooner or later you’ll need to write custom renderers for more advanced views — and that’s becoming really difficult.

Flutter (3 points) — Flutter seems to be the best option here as building UI with Flutter is like you were developing a game. Instead of physics engine you have widgets.

You still need to possess advanced knowledge of Dart. The whole UI has to be written in code what affects maintenance (we’ll go back to this later).

React native (2 points) — React native is using JavaScript and JSX to build it’s views. The solution is very similar to Xamarin Forms (the only difference is that we’re dealing with JSX instead of XAML)

Kotlin/Native (1 point) — You have to write UI twice as you were regular Android/Swift developer (only business code syntax is Kotlin). The good news is that you’re using native toolset to do this and you’ll have full IDEs support.

In case of UI simplicity Flutter is definite winner here. You can build comprehensive views using Dart only. Xamarin is providing XAML and that’s why it’s having more points than Kotlin/Native. Same amount of points is coming to React native as the solution is very similar to Xamarin Forms.

Building UI criteria seems to be the most crucial when dealing with cross-platform frameworks. Please don’t take it as your final decision as the devil is in the details. General truth is the easiest it is to build UI the more limitation we have in the future and that leads us to next criteria: look and feel.

Criteria 3: Look and feel

Xamarin (2 points) — The views created in Xamarin are using target platform SDK so they are identical to original ones.

Flutter (1 point) — The views created in Flutter are build in Vulcan. For today you can change the Cupertino skin (for iOS) or Material (Android).

React native (2 points) — The views created in React-native are using target platform SDK so they are identical to original ones.

Kotlin/Native (2 points) — Same as Xamarin/React. The views created in Kotlin/Native are using target platform SDK so they are identical.

There’s little sense in writing cross-platform apps that are not looking and performing as regular ones. This criteria is the most important for your end-users. You won’t get high notes in the store if your app is looking strange and kind of “not in place”. Flutter rendering engine is totally different than the one that’s on the target platforms. If you’re noticeable user you will feel that something is not right (like android animations are material-ish and feel different). You will also get into problems when new style of UI is introduced (for example if iOS SDK get major UI update — your app quickly get into problems).

Criteria 4: Being platform up-to-date

Xamarin (1 point) — Xamarin is using .NET. If there’s new version of Android support library — it must be wrapped to .NET. You need to wait for Xamarin team until is done. You are always at least one step behind target platform.

Flutter (1 point) — Flutter is a different world. It’s got it’s own view rendering engine. If there’s some cool new feature in the platform — you need to wait for Flutter update.

React native (2 points) — React native is always up-to-date as you’re using platform components together with JavaScript code.

Kotlin/Native (2 points) — Same as React… You’re using platform components together with Kotlin/Native code.

Criteria 5: Average code sharing level

Xamarin (2 points) — About 80%

You can share business logic, presenters, unit tests and part of UI. You still need to write platform specific services or view renderers (even if you’re using Xamarin Forms).

Flutter (3 points) — 90%

You can share practically everything. The chance you need to interop with Java or Swift is small.

React native (2 points) — About 80%

You can share business logic, presenters, unit tests and part of UI. You may still need to write platform specific services or views.

Kotlin/Native (1 point) — About 60%

You can only share business logic, presenters and unit tests. You still need to write views for both platforms separately.

You’ll never be able to share 100% of your code. Android and iOS are different as a mobile platforms. Sooner or later you’ll need to write platform specific behavior. Kotlin/Native seems to be definite loser here but that’s the price for being 100% flexible.

The creators of Kotlin/Native are not trying to create another common-denominator solution. Android UI is different than iOS and Kotlin/Native is ready for that.

Please also note that Kotlin/Native is not officialy released yet. After final release the level of shared code will increase. Let’s assume someone will create library for sharing the view tree (it’s not so hard to do it actually)… suddenly the amount of shared code will raise to 80%. And it’s only going to be better from here!

Criteria 6: How easy it is to write platform specific code (code interop)?

Xamarin (1 point) — You need to write missing 20% of your code. Your C# knowledge won’t help you in that. You still need to know the details of Android and iOS development. What’s more you need to know how platform specific invocation is wrapped in .NET (like instead of using View.GONE you need to use sth like that: https://stackoverflow.com/questions/36829454/xamarin-android-hide-a-textview). There’s practically no direct interop between Java/Swift and C#.

Flutter (2 points) — You need to write missing 10% of your code. You’re able to use interop between Dart and Java/Swift but it’s limited to primitive types and simple messaging (platform-channels). Things get ugly really soon but at least you are able to do it.

React native (2 points) — You need to write 20% of your code.

To do that you still need to know the details of Android and iOS development.

It’s a little bit better than Xamarin as you can mix React views with native ones. The interop is still limited to primitive types and there’s a lot of boilerplate code to communicate JavaScript with native world.

Kotlin/Native (3 points) — Code interop between Java/Swift and Kotlin are fundamentals of Kotlin/Native.

You’ve even got special language keywords like “expect” and “actual” to mix your code with other platforms.

Here’s another example when framework fundamentals are the most important. Kotlin/Native is definite winner here. You’re not limited to primitive types and interop is on much higher level.

Criteria 7: Reusing platform specific libraries

Xamarin (1 point) — You need to wrap java libraries and use the wrappers. In practice it’s barely working (I was able to wrap only one “.jar” of 20 — for the rest I got compile errors or dependency problems).

Flutter (2 points) — You can create platform specific package with platform specific dependencies and communicate with Dart using platform-channels. You’re still limited to primitive types.

React native (3 points) — No limits.

Kotlin/Native (3 points) — No limits.

Reusing platform specific libraries criteria is something you will never know how important it may become until you dive into the platform. Xamarin has bad fundamentals and you’ll quickly get into trouble. Flutter is a little bit better as code interop is possible. For Kotlin/Native or React: you’re good to go.

Criteria 8: Hardware requirements

Xamarin (2 points) — you can develop on Windows or Mac. It’s up to you but Visual Studio on Windows + ReSharper are more efficient than Visual Studio for Mac. You can install build server on Mac machine and stream it to Visual Studio on Windows.

Flutter (1 point) — you definitely need to have Mac to run iOS builds.

React native (2 points) — for simple proof of concepts you may use https://expo.io. For professional development you still need to have Mac (to debug iOS emulator).

Kotlin/Native (1 point) — you definitely need to have Mac to run iOS builds.

For cross-platform mobile development Mac is definitely a better choice.

Criteria 9: How framework is dealing with Android development?

Xamarin (1 point) — You stick to Visual Studio (or Visual Studio for Mac known before as MonoDevelop). The only support you have is for writing and refactoring C# code and XAML. When you need to touch some of Android XML files (resources, manifests) you get no support. There’s dedicated designer for Android but comparing to what we got in Android Studio it’s just embarrassing.

Flutter (2 points) — You need to use IntelliJ IDEA with Flutter and Dart plugins. In some cases you need to open Android Studio and work with both IDEs at once. There’s no support for designing UI interface. You need to use online designers and copy the code back and forth.

React native (2 points) — You need to use Android Studio for Android part and Visual Studio Code (or different JavaScript IDE). There’s no support for designing UI interface in both IDEs. You need to use online designers and copy the code back and forth. You also need to be connected to Chrome.

Kotlin/Native (3 points) — For Android you’re using multi platform projects on IntelliJ IDEA (CE or IntelliJ IDEA Ultimate) with Android plugin. Docs says you can also use Android Studio.

As you are using native toolset, you’re getting full IDE support: from code building, refactoring to user interface design.

Criteria 10: How framework is dealing with iOS development?

Xamarin (3 points) — You need to use same Xamarin IDE but iOS development feels much better. You have designer support for UI controls (you don’t need to create outlets as tool creates special partial class with bindings for you).

Flutter (2 points) — The situation looks very similar as for Android. For most of the time you’re using IntelliJ idea with dedicated flutter and Dart plugins. Sometimes you need to switch to XCode do write iOS specific code.

React native (2 points) — There’s nothing new comparing to Android. You need to use XCode and something else for JavaScript. To debug JavaScript you also need to use remote JS debugging (i.e. Chrome).

Kotlin/Native (2 points) — You work with both IDEs at once: IntelliJ IDEA and Xcode. Building multi platform project creates an apple framework that you’re free to use in Swift like any other external framework.

JetBrains are also offering Kotlin/Native plugin for AppCode so you can write Kotlin and Swift in one product (but you still need to use XCode for designing views).

As Xamarin is terrible for Android it’s pretty cool for iOS development. The problem is that if you’re writing cross platform you must use Android tooling as well.

For Flutter, React and Kotlin/Native we’ve got a tie. You need to mix between IDEs.

Criteria 11: How easy it is to find developer on the market?

Xamarin (2 points) — You need somebody who knows C#, Android SDK, iOS SDK, Java or Kotlin and Swift. At least there’re people familiar with C# (yes Dart… I’m referring to you :))

Flutter (1 point) — You need somebody who knows Dart, Android SDK, iOS SDK, Java or Kotlin and Swift.

React native (2 points) — You need somebody who knows JavaScript, Android SDK, iOS SDK, Java or Kotlin and Swift. Everybody likes JavaScript… right?

Kotlin/Native (3 points) — You need somebody who knows Android SDK, iOS SDK, Kotlin and Swift.

For Xamarin or React native you’re looking for 3 people in one person. In practice you need to train Android or iOS developer in C#/JavaScript or vice-versa. In best case you end in at least two teams. JavaScript and C# are definitely more popular than Dart*. That’s why Flutter got less points.

For Kotlin/Native you just need to take Android developer (probably knowing Kotlin already) and teach him/her Swift and iOS SDK. It’s much easier. Kotlin* is the second most loved language according to stack overflow survey and that’s a big bonus. You can also take iOS developer willing to learn Kotlin**.

* https://insights.stackoverflow.com/survey/2018/

** Yes, I know… the “real” iOS developer never will never-ever touch the robot until it’s blessed by Apple :P

Criteria 12: Maintenance

Xamarin (1 point) — If it’s so hard to find Xamarin developer on the market we shouldn’t expect the code to be written perfectly.

You will find code which is C# perfect (probably written by .NET developer) but not fitting to mobile platform. You can also find good mobile platform usage terribly coded in C#.

For Android you get practically no support from the tools (so dealing with unused resources or badly written xml’s are most common issue in Xamarin).

The framework is too complex. Apps sometimes crashes of MONO SIGSERV or out of memory errors. Sometimes you need to revert the code line by line to see what’s breaking the flow.

The good news is that you can debug all code in one IDE.

Flutter (1 point) — Flutter loves Dart. It loves Dart so much so even the views are created in Dart.

It seems to be good in the beginning but you need to be really careful when coding. If you take just one shortcut, your code will soon become maintenance hell. It’s also impossible to share the work between developers and UI designers like you can do in other platforms so don’t expect technical designer will help you out with views. You’ll also need to use view-debugging dumps to analyse what’s going on (and that is not pleasant task).

React native (1 point) — React native is addressed to web developers doing their first steps in mobile. That’s resulting in same consequences like we have in Xamarin. People working in React native projects got mixed skills and not always are able to code fluently in that mix.

Thankfully there’s possibility to debug JavaScript remotely otherwise it would be maintenance hell.

Kotlin/Native (2 points) — Kotlin/Native is using all the goodness you have in Android Studio/IntelliJ IDEA and XCode. You’ve got full access to view inspectors, profilers and everything else).

You even have tooling for writing common unit tests across all platforms.

The only thing that’s not clear to me is how to debug Kotlin code in XCode. It may be impossible just yet but AppCode plugin will support dual Kotlin/Swift debugging.

There’s nothing for free. Cross-platform development is always harder than regular one.

Criteria 13: Performance

Xamarin (1 point) —Xamarin performs well on iOS but terrible on Android.

Android was designed to work on budget devices and adding .NET framework virtual machine to the stack is not helping. Some old phones even need splash screens to load everything.

Flutter (3 points) — Flutter is using Vulcan in the same way as game engines.

If you follow the Dart performance rules (eg. isolates) your UI will perform really fast (almost 60 fps).

React native (1 point) — React apps need to run a heavy JavaScript machine in the background. Even official docs says that you need to pay attention to balance the workload between native part and JavaScript calculations. In the end, the apps got tendency to lagging.

Kotlin/Native (2 points) — Kotlin/Native compiles to native code or JVM. The goal of the framework was to be as fast as native platform… and it is.

Flutter is the winner here thanks to its unique approach to build the views in Vulcan.

Criteria 14: Market ready

Xamarin (3 points) — Xamarin is the longest time on the market. For a long time there was no vital competition for it.

Flutter (1 point) — Flutter is in release-candidate phase. It’s still hard to find good examples on how to use it but Google is keeping an eye on that and documentation is improving every day. On Flutter page you may find some showcase apps but the numbers are not that impressive like Xamarin or React/Native.

React native (2 points) — React native is supported by Facebook and React community for a few years. The framework is becoming a good alternative to Xamarin.

Kotlin/Native (1 point) — Kotlin/Native is also in release-candidate phase. Almost nobody knows about it as Google is mentioning Flutter more. It’s the newest player on cross-platform field.

And the winner is…

Not so fast… Let’s sum everything up!

There’s new sheriff in town

Photo by Glen Carrie on Unsplash

Kotlin/Native is the winner because it got the best fundamentals from all cross-platform frameworks I’ve ever seen. The framework goal is to provide native performance with the most powerful interop features. You can mix Kotlin with Swift and even do cross-inheritance. Interop is just perfect comparing to the others. Kotlin/Native is not a common denominator solution. This framework is aware that Android and iOS are different and there’s no sense to combine UI on both platforms.

You still need to take into account that Kotlin/Native is in beta but even that I’m sure it still deserves the first place. Most developers (or at least 75,8% according to stack overflow) want to start coding with Kotlin. That will boost Kotlin/Native adoption soon.

As you noticed I treated all criteria equally. You can use my article and apply your custom weight to things that are most important to you and choose your own winner.

Why it is so hard to create cross-platform framework?

iOS applications are similar to desktop apps. Of course there are limitations but in general the app lives in memory (suspended or not… its state is preserved). Android apps are like distributed systems: activities, services and fragments live its own lifecycle coexisting with broadcasts, receivers, alerts and other system components. The truth is that Android developers have much harder life. That’s why cross-mobile framework must come from Android knowing its memory restrictions and architecture. The creators of Xamarin and React native seems to forget about that. Adding another virtual machine or JavaScript interpreter affects performance and overall user experience…

The Flutter is different. That’s the only framework having its own view rendering engine. The problem is that Flutter apps seem different and sometimes unnatural. There’s also no separation between code and user interface — that will impact maintenance as your app grows.

Kotlin/Native comes from Android and understands it’s restrictions. The idea is to build Android application and transplant some of the code to iOS — and that’s perfect, efficient and much better solution. After Kotlin 1.3 is officially released — adoption will grow rapidly and the amount of shared code will increase.

Thanks for reading! I hope this article will help you choose cross-platform framework for mobile.

--

--