Native vs. Hybrid: developing cross-platform mobile apps

Jon Hocking
By Jon Hocking under Insights, Engineering 30 July 2014

This post was originally written and published by iOS Engineer and former TABber, Marco Sero.

As developers, we like to argue – a lot. And arguing about different technologies is probably our favorite topic of all.

Since the launch of the original iPhone back in 2007, it was clear that whoever wanted to build an app at the time had two different choices: going the safe and inexpensive way, using existing web technologies (HTML and Javascript), or investing time and money to develop the skills required to build a completely native app.

Not much has changed in the past 7 years. App developers can still choose the technology they want to use to develop an app for a specific platform. One thing that did change, though, is the way these two different technologies can interact together.

Note: this post isn’t about presenting the different toolchains to write cross-platform apps in different programming languages, such as Xamarin (C#) or RubyMotion (Ruby). These can be viable options, so definitely check them out.

The Desire for Cross-Platform Mobile Apps

The belief ‘write once, run everywhere’ is still alive and kicking.

There are so many different mobile platforms that it’s perfectly understandable, when committing financial resource to building an app, that you’d want to make most of it. So, if you have ever built an app for a client, there’s a good chance that you have been asked to make it cross-platform. You’ll be told it has to run on iOS, Android, Windows Phone and…Blackberry (just kidding). And, when you think about it, given websites run across different devices, it’s not surprising that some people expect the same result from a mobile app.

Three Different Approaches

So, once the client tells you they want a cross-platform app, what do you do? Panic? Of course not. There’s a better way: present them with different choices.

Option 1:

Go completely cross-platform (sometimes called a ‘mobile website’)

The Pros

There are several advantages to developing a mobile app in the same way you develop a website. The most notable advantage is probably the amount of code shared between the different platforms: the Javascript library that you’ll write to download and parse the content of your app will be reused; the HTML template for a widget view will be reused; the model to organise and store your data will be reused; and so on. It’s impossible to deny that this is a big tick. If your client just wants to save as much as money as possible, then this is definitely the best option.

The Cons

But with this great big tick, there are some big cons too. While developing an app, it’s important to keep in mind what your users are expecting and are used to. iOS users are surely familiar with a tab bar at the bottom of the screen, to navigate between different sections. On the other hand, Android users have never seen one before, as they mainly use a side drawer in their apps. Accommodating platform-specific user experiences is probably the hardest part of developing a completely cross-platform app.

Also, remember that your Javascript code will run sandboxed in a web-view, which is known to be one of the slowest and heaviest components to use in mobile development. You have to be really careful about everything requiring high performance, such as big images manipulation or graphics and 3D renders.

But, moving on, let’s say the client you’re working with wants both the slickest possible UX across different platforms, and they also still want to save some money reusing a sensible amount of code? Well, then there’s the hybrid option. Actually, two hybrid options.

Option 2:

Cross-platform core, interacting with native views

Who said that Javascript (JS) is only useful if it’s just used in a webview to manipulate HTML? That’s, like, so 1990s. Nowadays, JS is being used to write pretty much everything. Why shouldn’t we use it to write our shared business logic?

Every app, even the simplest one, has some kind of business logic that is required for the app to work. The business logic for an e-commerce app could be something like performing a user’s authentication. Since we need the code to handle these kind of features in all the platforms we want to support, the idea is to write it in JS and create a well-defined interface to reuse the code, accessing the information on different platforms.

The Pros

The advantage of this approach is clear: you get the best of both worlds. There’s a good portion of JS that can be reused, and at the same time you get a slick native UX and UI. Both iOS and Android support running JS code without a web-view, which is great and makes this option even more appealing.

The Cons

The disadvantages may not be that obvious, but there are many. Both the JavascriptCore (on iOS) V8 Context (on Android) are largely undocumented frameworks, and the interaction between native and JS can be tricky and very cumbersome. Finally, it’s important keep that in mind because this approach hasn’t been widely used, so it could definitely represent high risk to a project.

Option 3:

Native core, with native navigation and feature-specific cross-platform views

As I mentioned, having a platform-aware UX is very important, probably the most important part of cross-platform development and potentially the biggest challenge for UX designers.

In this third approach, the transitions between different sections and views within the app are performed with native components, to keep the UX close to the platform (as we did in the second option, too). The difference with this approach is that the core business logic is native as well, to make sure it plays nicely in the platform’s ecosystems and to make the model-view interactions seamless. But how is code reusability reached with this approach? Simple, with feature-specific cross-platform views.

The Pros

The main advantage of this approach is its flexibility. If you have a particular view that requires complex and fast animations, then think about using native technologies. Or, perhaps you’ve another view that’s mainly static but has a complex and non-standard layout? What about taking advantage of HTML and responsive CSS? This architecture guarantees that you always have the right tool for the job.

The Cons

So, what’s the downside? The biggest downside is that it could potentially be the most expensive option, as code reusability is limited to the amount of cross-platform views. Obviously, the more web views you use, the more code will be reused.

Another disadvantage is that you cannot avoid the native JS interaction, and in some cases the effort required to get it working on different platforms seems to be more than actually writing everything native. But that’s a topic for a follow-up post…

So, what’s the first step?

When it comes to deciding an app’s architecture, make sure to consider and investigate all your options thoroughly.

The first thing to do is understand your client’s requirements and expectations. Most of the time, the client will ask you to save money and at the same time develop the best app in the world. Since it’s difficult to have both, it’s about figuring out where the most impact can be positively felt for the budget available.

What we learned developing cross-platform apps is that the development speed doesn’t compare to the code reusability. In fact, writing cross-platform code for mobile apps can be a slow and tedious task for a lot of different reasons. Development tools like web view debuggers are simply not as powerful as native Objective-C and Java debuggers. For that reason, platform and device specific CSS and Javascript issues, (which are unfortunately very common), are more difficult and time consuming to debug and fix.

If you have decided to follow the third approach, we have some recommendation on where to use what. As a general rule, avoid cross-platform views for anything that has something to do with navigation and animations. These are the sections where you want your app to shine. The same can be said for anything hardware-related: gestures, multitouch events, geo-location tracking etc. are much easier to implement with native technologies.

I would personally recommend using cross-platform technologies for views that need to be represented with standard HTML components. A good example is a login or registration form. Forms are simple HTML markups and have been around for decades. Another example are tables: creating a table with an unstructured layout can be more complex with native technologies than it would be in HTML.