In part 3 of our Cross Platform App Development series, we explore the two leading approaches of cross-compiled development: Xamarin and React Native.
So many options, so little time. As you may have read in the first post in our Cross Platform App Development series, there’s an abundance of tools for developing mobile experiences. Fricken’ shedloads. Before development, we must consider the pros and cons of each tool — Native, Cross-Compiled, or Hybrid Web — in order to truly offer the right fit for the client. In this article, we’ll explore two leading approaches to cross-compiled development: Xamarin and React Native. Following this, we’ll draw a few conclusions to get your conversation started.
What is Cross-Compiling?
Cross-compiled applications are applications that are built from a single code base, but targeted at different destination platforms. They build applications that run without a translation layer on each target platform, leading to native performance while being able to write for multiple platforms at the same time.
The following are facts (and one falsehood) about Xamarin:
- C#-based! Xamarin is part of the excellent Visual Studio suite of development tools. Developers can target iOS, Android, and Windows from a single codebase.
- Now part of Microsoft! Xamarin enjoys adoption by a healthy community of developers (1.4 million at this time of writing).
- Mature! Originally born from the Mono Community in 2009 (MonoTouch for iOS) and 2011 (Mono for Android) [cite wikipedia?], it’s enjoyed a loyal following among C#/.NET enthusiasts and open–source advocates since inception.
- Metal! A new black metal band.
React Native takes a very different approach to development than Xamarin. Where Xamarin sticks mostly to traditional mobile development paradigms, React Native (as its name implies) takes inspiration from reactive programming concepts to lay out interfaces.
Tackling Platform Differences
Xamarin breaks the cross platform problem down by wrapping most native APIs in C#, which are shipped in .NET Assemblies called Xamarin.iOS and Xamarin.Android. Anyone familiar with writing iOS native code will see one-to-one matches for classes and methods in these Assemblies.
Xamarin also ships with another framework that can be a boon to developers: Xamarin.Forms. Xamarin.Forms provides a platform-agnostic approach, building UI for multiple platforms with the same code. Portable Class Libraries (PCLs) supply cross platform wrappers for other features, such as file I/O or database connectivity.
React Native takes similar approaches, but in the reverse order. Developers are encouraged to start with a platform-agnostic solution, and make only minor changes on a platform-specific basis. Opting into platform-specific UI elements is a last resort. Use of platform-specific features is more difficult; while it’s possible to target them with native modules, doing so requires you to already know how to develop for each platform.
One thing to remember with any cross-compiled approach is that there will always be points of divergence in your code; in these cases, you will have to fall back to platform-specific implementations.
Now, let’s consider those burning questions we mentioned in our introductory post.
What type of user experience will there be for the project? Are you looking to have something that is exactly the same across devices and platforms or something that is more tailored to the platform experience?
Xamarin.Forms is a viable option for providing all platforms with a basic UI: displaying static data and assets, and taking cursory input from users. Developers can also make platform-specific modifications, such as custom padding values for UI elements. For more complicated interfaces, Xamarin.iOS and Xamarin.Android allow you to implement UI in a platform-specific manner instead.
React Native shines in situations where you’re more concerned about consistency of brand or experience across platforms than in adhering to platform standards. React Native makes it easy to support identical UIs across different operating systems. However, the React Native UI elements are based on the most basic elements on each platform and won’t tend to look like a native app.
Who is on your team? Do you have a team of experts or interest in a particular platform? Generalists? Or potentially separate teams? How about your QA team?
In the case of Xamarin, familiarity with C# and the .NET framework are an asset to any developer, though you’ll need to know the specifics of the platform if you’re using Xamarin.iOS / Xamarin.Android. C# is a popular language and knowledge is prevalent. Strategically, it may make the most sense to cross-train C# developers on platform specifics as the need arises. One could also consider a scenario where there’s a ‘divide and conquer’ approach involving cross-training iOS and Android experts on C#/.NET to take any heavy lifting on their respective platform.
What are the most complex components of the project? Are they UI, business logic, systems integration, or a mix of several different things? Are you accessing lower level items that might only exist on certain types of systems (rfid / sensors / etc.)?
Some lower-level technologies will require additional work. Bluetooth Low Energy is a handy example. APIs are supplied by each platform, but the calling conventions are completely different. Any interaction will require a middle layer to be written, translating each platform’s separate APIs to a shared one. Early on, you’ll want to evaluate the development cost of anything more low-level.
How flexible do you want your experience to be? Do you want to require updates in order to change large components or does it need to be more dynamic?
Distributing an app written in Xamarin or React Native is very similar to distributing an app written with native paradigms: An iOS IPA or Android APK is generated that you upload to each platform’s store as usual.
These technologies are more dynamic, however, during development. A single codebase makes it easier for developers to hop between platforms, polishing each without having to “switch mindsets”.
Are there existing things that you might want to (re)use? Like libraries, previous versions, or open source projects that might help with the project?
Existing pieces of an application may be as much of a commodity for a company as running water — Redfin’s MLS data, Alaska Airline’s modeling of flight information, yadda yadda. In cases where these pieces are already firmly established, either within your company or by third parties, there’s an opportunity for reuse. In a native approach, this kind of reuse can seldom be considered without moving it server-side, denying the customer the savings in the process. Cross-compiled apps are ideal for sharing business logic across platforms. Both Xamarin and React Native support this.
Xamarin is a great option for thin clients wrapping complex business logic and data models. In situations where much of the product is data-driven or there’s complex business logic, this is an option to consider.
The React Native community is nascent, but active. There are a lot of React Native-specific modules available. You can also take advantage of a lot of existing NPM modules; most will usually Just Work™ in React Native.
It can be hard, however, to judge the quality of individual libraries in these platforms. Because the communities are smaller than the native platforms, libraries don’t get quite as much support or scrutiny. This can lead to issues where a library that looks good might be more trouble than it’s worth. It will be difficult to use any existing libraries you’re familiar with from native development, such as iOS’s Alamofire.
In considering your development path forward, you’ll need to weigh much. In this post, we’ve outlined our thinking when talking to clients considering cross-compiled applications, and hope you’ll find it useful as you establish your own road map. Our next post will cover similar ground when considering a purely web-based solution.
Read part 2 of our Cross Platform App Development series: Building Native Apps.