We have come a long way in mobile development since the very first app was released in 2008 to the Apple App Store. The tooling and approaches to developing mobile applications has grown significantly, bringing choice paralysis along with it. I decided to take this warm summer afternoon to analyze two popular technologies used for cross-platform mobile development today: React Native and Xamarin.
I should mention I am a two-time decorated Xamarin Certified Mobile Developer and I do have a bias towards Xamarin, C#, and the .NET ecosystem. I will do my best to layout my observations in an unbiased manner. So lets get on with it…
The original way of developing a mobile application for multiple platforms like iOS and Android involves creating two entirely separate applications. One version of the application is coded entirely from the ground up using Objective-C or Swift for iOS. Then another version is built again entirely from the ground up using Java or Kotlin for Android. This is what Apple and Google officially support and provide as the default way to code your mobile apps.
Separate tooling, business logic written in different but similar ways, different programming languages all add up to frustration and longer development cycles. It is 2017 and some of the biggest names in technology (i.e. Airbnb, Facebook, Slack, Pinterest) are using cross-platform development approaches to build their own apps.
The Cross-Platform Approach
Cross-platform mobile development is exactly what it sounds like. You code something once and then share it among one or more of the platforms you are targeting.
React Native and Xamarin are the major contenders everyone seems to be talking about right now. They both have a huge community surrounding them, third party libraries, and documentation.
When looking at any cross-platform development technology, I have assembled this general list of characteristics that I believe most can agree on to ensure it is a reputable framework. This can be useful in weeding out the Phone Gaps (hybrid frameworks) of the world:
- Native Performance – if your app does not perform well or users have to wait, they will not be coming back.
- Native UI – native user interface controls give users the familiar experience they have come to expect on their chosen mobile platform.
- Consistency – The same features, in the same way, always.
- Simplicity – The simplest solution is most often the correct solution. No other practice can give you a free lunch like a properly developed, reusable codebase.
Shared Code and Shared UI?
The level of code sharing you can achieve involves several trade offs. React Native and Xamarin native both offer the ability to share common code like business logic and network requests. This ensures about 75% of your app on average will behave the same no matter what platform it runs on and you only had to write it one time. I get the feeling from a lot of native proponents that native development is a winner based purely on the native UI experience and performance it can deliver. Nay I say.
Stack Overflow’s 2017 Developer Survey asked over 64,000 developers about their tools, technologies and preferences. The survey tells us React is the most loved and least dreaded technology among developers while Xamarin did not even come close in comparison being the eighth most loved and second most dreaded technology.
In trying to understand why React came out so far ahead compared to Xamarin, there are a couple of factors to consider. The vast majority of our industry is composed of web developers at 72.6% compared to just 23% for mobile developers. The survey also doesn’t explicitly call out React Native but simply “React” which I suspect is accounting for the web arena more than mobile.
Although many large companies such as Facebook, Airbnb, and Walmart trust React Native with their mobile experience, it is a bit of a self-fulfilling prophecy. The more big companies use a piece of technology, the more people get attracted to it. Even if the technology isn’t worth the hype (not saying that is necessarily the case here).
Truth be told, I have not had extensive experience working with React Native yet but planning to build our next app at work with it. I was impressed with how quickly I could build and run an app in the simulator after all of the tooling was installed. The breadth of libraries available is also impressive. Every time I tried to search for a plugin/component needed from the past, I found one or more variations available.
Xamarin native essentially provides 1:1 access to every method exposed by the underlying platform. Take a look at the Android code below. If you are coming from a native background it should look comfortably familiar. It’s just written in C# instead. Xamarin native exposes the native APIs in C# so you call them as if you were in the normal platform language. You still have Android layout files, activities and adapters. This makes the vast number of examples and code snippets on the web easily reusable. You have the complete power of the underlying platform at your fingertips.
public class MainActivity : Activity
protected override void OnCreate(Bundle bundle)
Xamarin native gives you the flexibility to create your UI with complete control. No manual bridging code necessary as compared to Xamarin Forms or React Native. Common code like network requests and business logic can live inside of a shared portable class library, ensuring the same behavior for every platform.
Xamarin Forms is a higher-level abstraction (like React Native) allowing you to build native UIs for iOS, Android and Windows from a single, shared C# codebase. The goal is to render the native controls of each platform. So when you declare a button, it will be a
UIButton on iOS and a
Button on Android. The image below was taken from the Xamarin Forms website and shows how Forms achieves the native platform look by default.
React Native is Xamarin Forms
If you consider React Native from the perspective of declaring your UI with some markup that abstracts one or more underlying platforms, then you start to see similarities to Xamarin Forms.
Oops! Need a native API call or user control because it’s not exposed by the higher-level markup of React Native or Xamarin Forms? You create a custom renderer in Xamarin Forms or a native module in React Native.
Both frameworks are effectively “poking a hole” in their shared code to communicate with the underlying native APIs to invoke native functionality.
I am surprised to find Microsoft is actually jumping on the React Native bandwagon as they have also created a Windows Phone React Native implementation so you can now also target the phone platform everyone laughs at. They also pioneered Code Push, a cloud service enabling React Native developers to deploy mobile app updates directly to their user’s devices. It’s smart they are covering their bases on multiple fronts in case one technology no longer has support of the wider community.
The numbers for Xamarin denote the combined totals from Xamarin.Android and Xamarin.iOS GitHub repositories. As a .NET developer the numbers are a little depressing. React Native has managed to outpace Xamarin in some aspects with the relatively short time it has been in existence. Part of the reason for the unbalanced popularity could be partially due to Xamarin only recently being open sourced vs. React Native being open sourced from the very beginning, driving a larger community behind it.
|# GitHub Stars||1,576||53,228|
|# GitHub Contributors||91||1,448|
|# Twitter Followers||59,200||16,400|
|Maps to Native UI Controls||Yes||Yes|
|Simplicity||If you are comfortable with the
What platform should I use?
Although this is highly opinionated I have a picture forming in my mind based on my experiences with native, Xamarin and React Native so far (each with varying degrees of experience).
Use native development with Swift for iOS and Java/Kotlin for Android when you are highly certain you will only be building an app for a single platform. Of course, pragmatism shows that is rarely the case. Performance is also no longer a contender compared to cross-platform solutions as they are on par with native performance. So it is unlikely you should go with this option unless you are just anxious to waste more minutes of your life.
Use Xamarin native development writing C# for all platforms but utilizing the platform-specific layout files in Android and storyboards in iOS when you are developing highly customized UIs for each and plan to target multiple platforms. This gives you the best of both worlds: complete UI control as Google and Apple originally intended but also sharing code such as business logic and network requests.
Use Xamarin Forms development when you are targeting multiple platforms and want to render the native controls of each platform with shared UI code. Forms really shines when you just want to use the default native controls out of the box with little UI customization. It’s also perfect for small teams to achieve higher velocity allowing them to code for multiple platforms at once.
Use React Native development for the exact same reasons you would use Xamarin Forms mentioned above. Seriously. Although I am getting the feeling customizing the UI with React Native is going to be easier than Xamarin Forms and also allows your non-programmer designer to get more involved due to the familiar web-style markup which is a huge win. React Native is also great if you identify native plugins you wish to use in your project but still want shared code. The community support around this framework and the speed at which it moves gives me the “feeling” that it will be less flaky than Xamarin Forms but as with any higher-level representation, be prepared for leaky abstractions.
So, where does this leave us?
I have successfully built mobile apps with Xamarin Forms, native Android, native iOS and I’m just now dipping my toes into the React Native sauce. Any future personal projects I build will likely be based either in Xamarin or React Native. Both have a huge community around them and the ability to share code across platforms means I can move faster than my purely native brethren.