If you’re going to be starting a new mobile app on both iOS and Android today, I recommend either Native SDKs or React Native as your development platform. The fully native approach offers the most long-term reliability with the best support while React Native comes with a lot of conveniences that are worth a look.
About a year and a half ago, I had the privilege of speaking at MN.IT Week and Mobile Twin Cities about the spectrum of development options available to technologists looking to create mobile apps. I discussed the pros and cons of the most viable options and offered my recommendations. As is usually the case with any technology, a lot has changed in the past 18 months. Here I’ll revise the main points of my original presentation to reflect those changes – both in terms of platform improvements and community direction.
The approaches I’ll cover include Native SDKs, React Native, Xamarin, Xamarin Forms, and Cordova. While there are certainly other frameworks for developing mobile apps, I don’t consider any of them viable or popular enough to make sense – support and resources will only get more and more scarce with time.
Native SDKs – ★★★★
Native SDKs, meaning the standard tools and API that Apple and Google supply for building apps on their respective platforms, have always been my go-to choice when recommending a basis for architecture of new apps. While React Native is quickly improving, that hasn’t changed. In general, this approach gives you the best long term support and the most definite and clear access to anything you might want to accomplish in your app.
- Best device support – Developing for watch or third-party external devices is a snap.
- Quickest access to new features – Other frameworks won’t support the latest feature on release. Native lets you in well before launch.
- Automatic OS standards – Platform-standards for navigation and UI are automatic or very easily adhered to.
- Best documentation – New API are easy to learn and apply through official and third-party guides and resources.
- Safe – Far lower risk of API deprecations or breaking changes.
- Most built-In features – Easy to implement things like network access or local database without worrying about choice of third-party libraries.
- No code sharing – Your app will have to be developed twice, once on each platform. Note that this does not necessarily mean that it will take twice as long or cost twice as much. TCO in the long term might actually be cheaper, and timeline goals might be more attainable depending on your resources.
- Specialized languages – While Java on Android is a widely-used, standard language, Kotlin is not. On iOS, Swift and Objective-C are really only used there. This can make skill transfer and hiring challenging.
- Compile times – Having to re-compile to verify changes can be time consuming depending on available hardware and the size of the app.
- Proprietary layout – The constraint-based layout engine on iOS can be a pain, and it’s contrary to layout in other dev worlds.
- Package management – Integrating third-party code on iOS (compared to other platforms) is clunky at best.
- Tooling – While Android Studio is great, Xcode for iOS is… not very good.
React Native – ★★★★
A year and a half ago, I was very reluctant to recommend React Native (RN) for anything beyond experimentation. While I loved the pattern and the idea, it was just too immature and lacked established standards for basics things: navigation and local storage chiefly among them.
Since then, a lot has changed and stabilized. The excellent support and drive from Facebook has kept RN going in the right direction. The popularity of the React framework among web developers has given RN a big boost in the pool of capable engineers. Navigation has a standard that works great, local storage is well supported, and third-party and open source libraries like Realm support RN as a first-class platform.
Lately there has been a bit of controversy around RN. Airbnb, an early major supporter of RN, recently wrote a series of blog articles about why they’re pulling away from it, and Udacity has followed suit. On the other hand Discord has affirmed their love of RN on iOS while switching back to native for Android. Finally, and surprisingly, the most compelling support for RN has come from Microsoft. They announced recently that major components of Office 365 are being developed with React, React Native, and Electron.
Finally, as a developer with deep experience in native iOS work and quite a few years on front-end web, there is something very fun about RN.
- Fast development – Features like live reloading and hot reloading make realizing code changes very quick and pleasurable.
- Flex layout – The choice of a popular and easy to understand layout technology makes developing React Native screens and components very easy.
- Code sharing – It’s possible to develop your whole app on two different platform with little to no redevelopment. Even when following recommended standards, only parts of your UI layers will need to be redeveloped per platform. It’s even possible to share code with web apps.
- Popular and growing – It’s the most requested cross-platform framework I’ve seen from clients.
- Immature – While RN seems to be stabilizing, I hesitate to recommend anything with a version number that begins Zero Dot. This brings the risk of breaking changes with any new version; certainly many things have changed in even just the past year.
- Debugging inconsistency – Debugging a RN app happens in a different environment than running it in release mode. This can lead to issues that are very hard to diagnose.
- Android support – While RN on iOS feels very quick and polished, on Android it still seems a bit… off. Debugging and consistency is certainly trickier on Android. Discord recently made the choice to use RN for iOS, but they’re sticking with Native SDKs for Android for the time being.
- Native modules – If you need to support a device or consume a library that doesn’t already have RN binding libraries, developing and supporting those libraries yourself can be very cumbersome and time intensive. If your project requires more than one or two, I don’t recommend RN.
Xamarin – ★★★
Xamarin was once my preference for cross-platform mobile architectures. A very complete translation of Native SDKs to the C# language and .NET tooling, it made the mobile world accessible to seasoned C# engineers. Apps can be structured to provide a lot of efficient code sharing while UIs remain sufficiently separated to allow full conformance with platform standards.
That said, through many projects, I can’t say I ever enjoyed working with it. Xamarin is a great tool in the hand of the right person, but that person is rare: strong C# developer who also has deep knowledge of the iOS and Android SDKs. While I happened to be one of those people, they’re few and far between in the market. Furthermore, despite the knowledge, working with Xamarin was never fun. The tools and build times always seemed to get in the way. I’ve also seen a lot of former Silverlight/WPF developers too clung to their old patterns to do Xamarin correctly.
Nevertheless, good work can be done with Xamarin, especially with the right team.
- C# – An excellent language with a lot of users, making mobile development accessible for .NET devs.
- Full translation of Native SDKs – Usually by day of release, Xamarin supports the entirety of the Native SDKs. This generally means you gain all the support for new devices, OS standards, and built-in features without lag time.
- Code sharing – A well-architected Xamarin app can share a lot of code – networking, database, caching, view models, etc. Only the UIs need be written per platform – and there are libraries available that reduce the need for that (although I don’t recommend them).
- Nuget – The .NET package manager gives your mobile project access to a lot of reusable libraries online.
- Visual Studio – Being able to develop for mobile in Windows on Visual Studio and even debug over the network gives devs one of the best IDEs around.
- Mac Tooling – Visual Studio for Mac lags way behind its Windows counterpart, and layout will still usually be handled in Xcode.
- Package size increase – Xamarin makes the size of your deployment packages larger, although depending on their size to begin with, this may be negligible.
- Cumbersome – In my experience, the Xamarin projects I’ve worked on have just felt heavier: too much ceremony and a little unwieldy.
- Native cons – Because Xamarin is a full translation of Native SDKs, you get a lot of the same negatives – chiefly compile times and proprietary layout.
Xamarin Forms – ★★
Xamarin Forms is a layer on top of Xamarin that allows for truly cross-platform UI, typically written in XAML. I don’t love it, but it’s certainly a useful tool for an experienced .NET team who wants to build apps with minimal UI customization and an enterprise mindset. No change from my earlier recommendation… other than to say if Xamarin Forms meets your needs, consider learning React Native instead.
- More code sharing – Because Xamarin Forms has its own UI library, you can write UIs that are shared between iOS and Android more easily, although they are limited.
- XAML layout – XAML as a layout language can be attractive to developers who are familiar with WPF or Silverlight – although as one myself I’m tempted to put this in the Con column.
- Enterprise targeted – Because it’s intended to serve the enterprise market, its boiled-down offering can make for more rapid development with those types of apps in mind.
- Less customization – If you’re satisfied with the UI capabilities that Xamarin Forms offers, you might be fine working with it. If you need more customization, it will be difficult times – not recommended in that case.
- It’s Xamarin – See all of the cons for Xamarin above, and some of the pros I suppose.
Cordova – ★★
Cordova (AKA PhoneGap) is one way to package web code and deliver it in app form. The major distinction between Cordova and the rest of the options here is that with it you’ll get web rendering – just like a page in a browser. This is opposed to native rendering – what you typically see in native apps. While modern high-end hardware lessens the importance of this, mid to lower level devices will not render or animate with the same fluidity you might expect.
If that’s not a major concern and you’ve a lot of web code you want to reuse in your app, Cordova is a sensible choice.
- Familiar tools and languages – Developing your app like you would any web site can be convenient for developers already familiar with web techs.
- Code sharing – Very easy to write your app once and share between iOS and Android… and your potentially already existing website.
- Web rendering – Cordova apps will not appear as fluid or responsive as native-rendered apps like any of the above technologies. The older the user’s device, the more obvious this difference will seem.
- Cumbersome – The development overhead of the Cordova apps on which I’ve worked felt very cumbersome to me. Too many headaches to make it worth it.
- Upgrading can be painful – More headaches here. Upgrading Cordova libraries can introduce many breaking changes, but it can also be required work in certain situations.
There we have five viable options for mobile development in varying degrees of native and cross-platform. While I generally advise towards Native SDKs, there are very good reasons to go with cross-platform tools. Please keep in mind that total cost of ownership and time to market should not be among those reasons. Code sharing does not necessarily imply your app will be written more quickly, nor does it indicate that your app will be less expensive to develop and maintain in the long term. While it might for certain apps and teams, it will not for others.
Instead, base your decision on the skills and levels of your current staff, the availability of trainable or already skilled resources, your propensity to respond to change, and your desire for platform stability.