Why We Ditched Hybrid App Development

Recently we've had some customers ask us about hybrid applications and if they would be a good fit for their business. For a little while, cross-platform mobile apps were very appealing to us since we could build one code base that would compile for both iOS and Android. But after a few negative experiences, we decided it was best to switch back to true native mobile app development. We want to share the reasons for this change.

1. Instability

Cross-platform frameworks tend to be unstable in comparison to the native SDKs. Previously we had built an app using Ionic, one of the top frameworks for developing mobile apps with HTML5. When the iPhone X came out, design standards changed due to the full sized screen of the device. Ionic promptly released an upgrade, which allowed us to support the new device properly.

Except it wasn't that easy.

Upgrading Ionic required a new version of AngularJS (the underlying Javascript framework), which contained breaking changes from our previous version. Overall, the process set us back multiple days, which is simply unacceptable.

Despite Ionic giving us troubles, at least it's not in beta. React Native has been popular for a few years now and it still has not reached version 1.0 yet (as of this writing, stable React Native is version 0.57.0). While software is in beta, it's safe to expect breaking changes along the way. This can make updating apps very difficult, as was the case with our Ionic experience.

Contrast all this to native: iOS and Android have been extremely stable for years now. Android is notorious for supporting old versions of the OS for many years. Even Apple, who launched the Swift programming language in 2014 as the new way to build iOS applications, still supports Objective-C as a viable method for building apps.

2. Differences in Standards

One of the main reasons companies choose cross-platform frameworks is to share code between iOS and Android mobile apps. "Build once, run anywhere" is a common phrase spoken in relation to this. In practice however, not only is this unlikely to be true, it's also not a good idea. iOS and Android are very different operating systems, and the user experience is not the same. Android utilizes Material Design as the standard for UI components, while iOS uses a version of Flat Design. Some differences are subtle, such as visual effects while tapping buttons; others are more drastic, such as tab bars differeing in location (iOS places tab bars on the bottom of the screen, while Android expects them on the top).

All this being said, there are differences in UI/UX guidelines that need to be taken into account. We find it easier to design for both platforms separately and find similarities where we can, rather than design once and change things we see fit. Because of this, a large chunk of the application code winds up being platform-specific anyways.

3. Troubleshooting Issues

Regardless of the size of the project, it is imperative that debugging and troubleshooting fits well into the workflow. This includes not just troubleshooting while developing, but also troubleshooting issues after launch. The last thing we want is for our app to crash and we don't know about it. Crashlytics is a lifesaver in this regard. We used Crashlytics in one of our first mobile apps and were astounded when we received email alerts every time the app crashed, with the exact line of code that caused the crash. With this data, we were able to fix issues and release updates before most users ever saw the problem. Crashlytics can technically be used with cross-platform tools like React Native, but it's far from intuitive. The truth is, native tools are fantastic, but are nearly useless if you aren't developing with the native platform.

4. Platform A.D.D.

This point alone is enough to deter someone away from cross-platform development, and was ultimately what pushed us over the edge. No one can decide on a tool and stick with it. On some level, this is viewed as a positive. It's great that we have so many frameworks to choose from. But when building a long-term mobile strategy, we need confidence that the tools we choose will still offer the best technology years from now.

Phonegap was the first mainstream hybrid framework. Then came Ionic. A couple years later, React Native took the throne. And right now it looks like Flutter is soon going to overtake React Native. In 2019, there will probably be the "next big thing" that will emerge. We've heard the arguments, we've read the blog posts, and it's just the same story over and over again. If you don't believe me, just take a look at these:

Why Ionic is Reigniting the Native vs HTML5 Debate - Treehouse Blog

7 Reasons Why React Native Is the Future of Hybrid Mobile Apps

Why Flutter Will Take Off in 2018 – codeburst

We can't justify choosing a cross-platform framework over native development when we can't reliably predict its shelf life. Regardless of how much technology changes in the next 3-5 years, we know native SDKs will exist as long as the iOS and Android are still alive. And this is a critical selling point for us--we want long-term value for our customers. A mobile app built today may not suffice 3 years from now, but we shouldn't have to rebuild the entire thing in order to keep up with technology.

Conclusion

So, does this mean we don't ever build cross-platform mobile apps? Not necessarily. Whenever possible, we try to build libraries that we can share between our iOS and Android app code. Both platforms natively support C++ as a programming language, and Go has tools to natively compile frameworks for both platforms. Generally we can achieve 20-30% code sharing between platforms. However, the difference between this approach and a full cross-platform app is huge. UI code is always written in the native SDK of the platform. Typically we will write shared libraries for high-level tasks such as network calls.

If you're in need of mobile app development, or need guidance on your mobile strategy, don't hesitate to contact us!