When you develop mobile apps, one of the first decisions you face is which front-end technology stack to use.
This made sense at the time, because until a few years ago, Microsoft and BlackBerry were still trying to play a role in the smartphone market with their operating systems and, to be able to reach the widest audience possible, developers had to support at least three platforms. Since the declaration of end of support for both Windows Mobile and BlackBerry OS, today it’s sufficient to release an app on iOS and Android to reach more than 99% of smartphone users.
This is why, today, there are many more aspects for developers, team leads, and architects to take into consideration when making a decision on the mobile frontend technology stacks, going beyond the dimensions of code reuse and performance.
Coding vs. Execution
Let’s define new concepts to look at the comparison: native vs. cross-platform coding and native vs. hybrid execution.
What do we mean by native and cross-platform coding?
- Native (coded) apps are developed with programming languages and tools that are offered by the company that develops the platform and the OS that they run on. For example, native iOS apps would be written mainly in Objective-C and Swift, whereas native Android apps would be written in Java or Kotlin.
- Cross-platform (coded) apps are developed in programming languages and tools not included in the development tools offered by the company that develops the platform and the OS that they run on. This is a broad categorization, including stacks and frameworks like Ionic, Xamarin, React Native, Apache Cordova, Flutter, and more.
Let’s now look at the difference between native and hybrid execution.
- Native (executed) apps are written in native or cross-platform programming languages and are then either compiled to assembly code ahead-of-time (AOT) or just-in-time (JIT), which still leverage native UI widgets. For example, apps written in Xamarin, React Native, and Flutter belong to this category. This is a recent concept, as supported by the fact that these frameworks have all been recently released (Flutter had their first stable release in December 2018) or in early stages of maturity (although often used in production, React Native versioning is still far away from release “1.0” as the most recent version at the time of writing is 0.59).
You can see a comparison of the IDEs, CLIs, OSs, and programming languages for each of the native and cross-platform frontend technology stacks in Table 2 of “Getting started with full-stack mobile development.” It’s worth noting that, in this article, the focus is on full code development stacks, so the parameters for comparison assume there is code to be written and you’re not using a low-code or no-code app building tool.
Tradeoffs for choosing a mobile development framework
First and foremost, let’s start by saying that adopting a full-native technology stack is the no-compromises solution for a mobile development framework. If you are considering using a cross-platform technology stack for developing mobile apps, you most likely have other considerations driving your decision (such as development time and code reuse) that may require you to make some tradeoffs. These tradeoffs are not necessarily about performance, but they do cover other aspects of mobile development, such as upgrade paths and timing of tooling and language support for mobile OS updates.
The main perceived tradeoff between native and non-native mobile apps is one of performance, with hybrid mobile apps performing more poorly than native mobile apps. By performance, I mean 2D mobile apps only and not 3D apps that require a 3D engine.
Even without 3D graphics, you want your mobile app UI to remain fluid, even during heavy data processing to provide a smooth user experience. Because mobile processors are multithreaded, you do not want your mobile app UI logic to run on the same thread where the data processing is taking place. While badly-written mobile apps will perform slowly on any stack, native mobile development frameworks have this capability built in and offer APIs to fine-tune the dispatch of operations on different threads. However, web apps and hybrid apps that are built on web technologies need to run their content on an embedded web browser and performing heavy processing, such as the parsing of a large API response within the browser, causes the UI to be blocked (or, alternatively, displaying full-screen “Loading” indicators to prevent the user from interacting with the UI).
Most recent cross-platform mobile development frameworks address the performance limitations in different ways and some of them qualify as native apps when speaking in terms of runtime.
- Xamarin compiles code ahead-of-time to ARM assembly language for iOS and the MonoVM virtual machine for Android, which sits at the same level of the JVM on the Kernel.
- Flutter compiles to 32-bit and 64-bit ARM code for iOS and Android.
All the approaches above have some limitations depending on platforms, and you should carefully look on the limitations page when designing your mobile app to see whether you have such complex requirements where a certain framework may not work for you.
Staffing or resources
If you decide to go with a cross-platform mobile development framework you will benefit from being able to develop apps for multiple platforms (iOS, Android or even Universal Windows Platform and Web) with the same skills. The potential tradeoff for staffing or resources is that you are building a team of “generalists.” Generalist designers will risk not knowing the capabilities of each target platform and will build UIs that are neither fish nor fowl. Generalist developers may not be aware of certain target platform-specific APIs and try to “rebuild the wheel” on another toolkit. You will want to ensure that your team has strong design and architecture guidance when staffing resources for cross-platform mobile apps.
Also, do not fall in the pitfall of believing that cross-platform mobile development frameworks are easier to use than native ones. More often than not, if you are building a complex app, you will have to use certain device-native features by using plugins or bridges that can only be written in native code. So, you will need senior developers with a high level of expertise.
Development time and code reuse
Time-to-market is always critical in new mobile projects, and companies are always looking for ways to reduce the time it takes to develop mobile apps as much as possible. While it is possible to build dual-native apps on iOS and Android side-by-side and release them at the same time, this method might require you to either stretch the development time or increase the team size.
A cross-platform mobile development framework, coupled with good application architecture, can help shorten the development time by increasing code reuse. For applications that do not make extensive use of frameworks, it is realistic to think in terms of 90% code reuse for the Xamarin, React Native, and Ionic frameworks. Some tools, such as Ionic, allow for the same code to be reused not just across mobile platforms, but also with web apps as well (by building Progressive Web Apps).
The potential risk of trying to maximize code reuse is that you risk losing sight of each platform’s specific strengths as you build for the average without taking advantage of platform-specific frameworks.
Future upgrade paths
The mobile platform landscape is constantly evolving, and you need to think about the lifetime of the mobile app that you are about to develop. The longer you want your app to remain available on the market without major rewrite, the more you will want to choose a stack that offers clear upgrade paths. Picking a technology stack that does not have a long-term roadmap or a very small support community will put you at risk of having to rewrite the app at a certain point in the future, which is a major investment. If you choose a native mobile development stack, the vendor will most likely provide a clear migration path, guides, and automated migration tools. Even when a major migration happens, such as Objective-C to Swift or Java to Kotlin, each platform vendor puts tools and support guides in place for the new languages. For cross-platform mobile development technologies, this risk is higher. To mitigate this risk, you need to select tools that are backed by wide communities or by large companies. The presence of a support fee can help in this scenario, but it might not be the most important factor if the vendor is a niche company.
OS updates – support, timing, and effort
This aspect means addressing the question “What happens when a new OS version is released?” and addressing some related questions such as “How quickly will my framework support the latest features?”
Native languages and tools will be supported from the day of release, while cross-platform tools will inevitably have a delay between the stable OS release and support of the same features within the cross-platform framework itself. You can address this tradeoff by considering these questions: “How vital is it for your app to support new features at launch day?” “Are you aiming to be on stage at Apple’s or Google’s conferences to display upcoming app features?” If the answers to these questions is yes, you will prefer a native stack.
You also need to consider the likelihood that the newest OS release introduces either API changes that require code modifications for the app to run efficiently in the most recent OS update or changes in the build toolkit that make builds fail. For example, when Xcode 10 was released, it included a new build tool that prevented Cordova-based Ionic Framework apps from being packaged properly on iOS. Although the resolution is often simple (in this case, you had to add a “build flag”), it still required work from our team’s DevOps specialists to identify the issue and seek help within the community for a resolution. Again, if you choose a cross-platform stack that has wide community support or vendor “push,” this trade-off is mitigated.
Development considerations for choosing a mobile development framework
With the above aspects clarified, let’s look at factors that might drive your choice between a native or cross-platform mobile development framework. The main driver for these considerations is driven by the type of app that you are building and its audience and the devices you plan to support. I am making an assumption that, as best practices, if you are working in an agile manner, you should have quick release cycles for all app types and aim for the best user experience in all scenarios.
What type of app are you building? (Audience, devices, complexity)
First and foremost, the mobile development framework you choose depends on the type of app that you are building:
- Enterprise apps that are for employee B2E, such as an audit tool or a plant maintenance application. These apps are expected to be long-lived, will likely be quite complex in terms of business logic, but you may not require immediate support of new OS features. With enterprise apps, your company might have a device strategy that dictates that all apps will be developed on a single platform only.
- Productivity apps that are B2C customer facing, such as a shopping app. You can expect these apps to be fairly complex, have a long lifetime on the store, and you want them to perform as best as possible, since your company’s name will be next to the App Store ratings. You can assume that you will need to target both leading platforms on the market, currently iOS and Android.
- Marketing apps that are B2C facing, such as an app for a campaign or a conference. These apps might be relatively simple, although they need to pack eye-catching features. With some exceptions, these apps will not need to remain in the app store for a long time and only be on sale during the campaign or event duration. Because these apps are for consumers, they need to be offered to all platforms on the market and you might even think of a web version.
- Productivity apps that are for business partners B2B, such as a wholesale order tracking app or an inspection app. From a complexity and use case standpoint, it will be very similar to an employee apps (fairly complex and with a long lifetime) but the main difference is that your company won’t have control over the devices strategy of your business partners, so you will need to build apps for multiple platforms.
How familiar is your team with mobile development tools?
When staffing your mobile app project, you need to know what mobile development skills you have on your team. If you are working in an environment that has strong knowledge of a certain language or certain tools, some cross-platform mobile development frameworks may fit your needs. For example, Xamarin offers tools for building fully native apps (from a processor architecture point of view) for both Android and iOS. Or, a team of React web developers can feel more at home building React Native apps than switching to native development languages.
Other than the differences in programming language, a common trait of many cross-platform mobile development frameworks is the support of a “hot reload” or “live reload” development approach. With this approach, because changes are not directly compiled to native code, when you make a change to a file in the development environment, the app is immediately refreshed on the simulator that you are using for development. Developers love this capability.
Independently of which cross-platform mobile development framework that your team might be familiar with, your team will need guidance from experts on the native platform. And, if the cross-platform stack does not offer a plugin out of the box for features your app requires, then you might need to rely on external resources for these features.
How complex is your app?
App complexity can be measured in many ways, but the number of included frameworks/SDKs and device features is definitely a good method for deciding between native and cross-platform mobile development stacks. Sometimes, app complexity is measured in the “number of app pages” (or screens), but that’s not how you want to measure it: a small app may require complex platform integration, so the complexity estimate should be done at the time of solution design, where your Lead Developer or Mobile Architect will make technology decisions on the frameworks and capabilities of the mobile platforms to deliver the requested business features.
If your app needs to include platform-specific capabilities (such as ARKit for Augmented Reality, CoreML for Machine Learning, or ApplePay on iOS), you’ll need to thoroughly research and validate whether it is worth it to build a cross-platform app and then adopt or develop plugins/bridges for these technologies or instead go entirely native.
Also, depending on the backend technology that you will use in your full-stack app, you need to add integration SDKs for databases, notifications, or API integration. For example, if you build an app for Salesforce, you will require the Salesforce SDK. The presence of the corresponding SDK for the backend system you intend to use is a key go/no-go decision for a certain technology. While all native tools have a corresponding SDK, some cross-platform frameworks do not.
How will you support your app after its release?
All software released to end users requires a form of support, from fixing bugs to making sure that the app works on new OS releases. Also, mobile apps are really never “done,” and you will likely build your app iteratively, adding features over time.
If you are adopting agile and DevOps best practices, bugs and enhancements become part of the backlog and are addressed in a subsequent release by the same development team that built the app. A shared codebase is a factor that can contribute to reducing the time you spend on resolving defects, as your team would fix the issue in a single place. Also, should your company take the not-recommended decision to outsource support to a separate team, a shared codebase can contribute to having less resources assigned to the support activities.
What is the expected lifetime for your app?
Before starting to develop your next mobile app, you have to consider how long you expect the app to remain on the market. While it’s true that mobile apps are short-lived compared to many legacy solutions, I believe it is realistic to expect a 3-year lifetime for your mobile app (before thinking of a major rewrite), especially in enterprise environments for employees.
Choosing a technology that ensures you can always upgrade to the latest support level offered by the mobile platform is key for apps that have a long lifetime, while it would not be a problem for marketing campaign or events apps, that may be rewritten or thrown away when their purpose is reached. Although some cross-platform stacks are supported by large companies, such as the case of Facebook for React Native, support can be dropped at any time without notice. Of course, with a large enough community, the project will live on, but it can be a tough selling point if you plan an app for a long lifespan.
In this article, I provided a set of tradeoffs and development considerations for choosing between native and hybrid mobile development frameworks.
What was once just referred to as “hybrid” has evolved in the recent years into more mature cross-platform development tools. Many drawbacks of early hybrid (web-based) approaches are a thing of the past and more clever ways have been developed to offer a cross-platform development experience to deliver performant native code.
Cross-platform frameworks offer, in some cases, more advanced features than native tooling. Think about hot reload or live reload: although Instant Run on Android and SwiftUI in iOS allow for something similar, this is one feature that was ported from hybrid back to native.
Cross-platform development stacks are powerful. And, as you know, with great power comes great responsibilities. In the past a cross-platform mobile development framework, (especially a web-based one) would be used to accelerate the ramp-up of junior developers or to offer a path for Web developers to quickly gain mobile skills. Now, with the sophistication of today’s mobile operating systems and the wide array of features and frameworks to build for, you need senior cross-platform developers and strong native guidance to deliver solutions that take advantage of devices’ latest capabilities.
You can’t go wrong building native apps: you will have a clear upgrade path, supported tooling on day-0 of new OS releases, and no performance trade-offs to make whatsoever. In conclusion, here are some rules of thumb for deciding whether to use a native or cross-platform mobile development framework. Nothing is black-or-white when it comes to technical decisions, and ideally you should always document all the factors that drive your choice:
- Are you building a complex mobile application, with heavy dependencies from native frameworks, or “first-of-a-kind” mobile apps on latest technologies? Build it using the native stack. Period.
- Are you building a B2C application targeting the stores, with an expected long lifetime? Build it using a native stack. Your team can still experiment with building partial features in cross-platform tools (for example, Airbnb and Facebook have been experimenting with React Native in this way).
- Did you do your homework and are you confident that your solution has a reasonable level of complexity, and are code reuse, staffing and time to market your main drivers? Consider cross-platform frameworks, bringing in guidance from senior native developers/architects/designers as needed.
The main driving success factor will always be your team: while the choice of the best-fitting stack will certainly play a major role, a motivated and truly agile team will be the determining factor to success.