Defining a New Breed of Cross-Platform Mobile Apps

Sometimes it feels like we’ve been arguing over which is better, a native app or a hybrid app, since the beginning of time, with dire consequences predicted for anyone who chose incorrectly.

You Must Choose

The debate became overheated when, in 2012, Mark Zuckerberg famously dissed HTML5 at the Disrupt conference:

When I’m introspective about the last few years, I think the biggest mistake that we made as a company is betting too much on HTML5 as opposed to native. – Mark Zuckerberg

But a lot has changed since 2012. First of all, HTML5 support is now so ubiquitous that even the term itself has begun to sound like an anachronism. Nobody really touts their HTML5 support anymore — it’s simply assumed.

In terms of mobile app development, the landscape has changed dramatically too.

The native development landscape changed significantly with introduction of Swift. This eliminated one of the major “pain points” of doing native development, at least according to some — Objective C.

Swift vs Objective C

Source: http://blog.shinetech.com

Cordova (aka PhoneGap) has improved for hybrid development, as has the WebViews that it relies upon for both iOS and Android. Projects like Crosswalk have even smoothed out the fragmentation issue that famously plagued Android. In addition, a large number of cloud-based tools, including our very own Telerik Platform, have even eliminated the complications of the setup and build processes for hybrid.

However, there’s much more today than simply traditional native or hybrid. For instance, solutions like RubyMotion or Xamarin, that compile to native from Ruby or C# respectively, have gained popularity.

More recently, a series of JavaScript-based solutions have been garnering a great deal of attention. These solutions have native UIs but aren’t purely native, as the underlying code is still deployed as JavaScript. They are built, at least in large part, with web technologies like JavaScript and, in some cases, CSS, but aren’t truly hybrid, as there is no HTML or WebView.

The most well known of these solutions would be React Native and Telerik’s own NativeScript, but there are a growing number of alternatives, both pre-existing (Appcelerator Titanium) and new (Tabris.js and Fuse).

In this article, we intend to define and place these JavaScript-based solutions within the app development ecosystem. We also will discuss what each of the different options for mobile app development — native, hybrid and what we’re calling “JavaScript Native” — brings to the table. In the end, as you’ll see, this is not a zero-sum game — all of these solutions can co-exist, offering you, the developer, a great deal of options for developing a mobile app.

What Defines Each Type?

Let’s start with a quick definition of what each type is before moving on to which of these options make sense for your next project.

Hybrid

The hybrid development approach was popularized by PhoneGap back in the early days of mobile app development. The term “hybrid” itself refers to the hybrid of native and web development approaches.

A hybrid app works by creating a native app that launches a WebView, or an embeddable browser instance provided by mobile OSes (i.e. iOS, Android, and so forth), and uses that WebView to drive your native application. Because hybrid apps are running in an embedded browser, they’re written using the same technologies you would use to build a web app: HTML, JavaScript, and CSS.

Today, most hybrid apps are built on top of Apache Cordova, an open source project that many popular mobile development platforms leverage, including PhoneGap, the Telerik Platform, Ionic, and more. Cordova provides a consistent set of JavaScript APIs to access device capabilities through plugins, which are built with native code. For instance, the Cordova camera plugin API lets you access your device’s camera using a call to navigator.camera.getPicture().

You can find a full list of available plugins at plugins.cordova.io. We (Telerik) also maintain a curated set of plugins at plugins.telerik.com.

Native

In the context of mobile app development, the term “native” refers to building applications using each platform’s native language and development tools. For iOS this means writing your code in Objective–C or Swift, and doing your application development in Xcode. For Android this means writing your code in Java, and doing your application development in Android Studio or Eclipse.

Native apps are typically associated with the very best performance, as you’re coding directly against the native platform APIs. But native apps are also associated with higher development costs, as developers must learn the how to build for each platform individually, with very little skill reuse across platforms (aka mastering Swift won’t really help you build an Android app).

JavaScript Native

The JavaScript Native approach to mobile app development was popularized by Appcelerator Titanium, and has come back into the spotlight with the recent release of both React Native and NativeScript.

Although JavaScript Native apps share some characteristics with hybrid apps, such as using JavaScript for application logic, overall, JavaScript Native apps represent an entirely different approach to building mobile apps, and as such, don’t really fit in the “hybrid” category.

For one, JavaScript Native apps do not use a WebView; there is no HTML, and there also is no DOM. Instead, JavaScript Native apps build their user interfaces using the platform’s native UI components. For instance the two videos below show the NativeScript Groceries sample app in action. Notice that the UI controls used are completely native iOS and Android controls.

Because JavaScript Native apps do not use HTML, all JavaScript Native frameworks provide an alternative mechanism for defining UI components, specifically, both NativeScript and Appcelerator Titanium use XML, and React Native uses JSX. As an example, a <button> element in NativeScript is actually implemented as UIButton on iOS and an android.widget.Button on Android, but the native implementation details are abstracted away from the developer.

One final characterizing feature of JavaScript Native apps is that they interpret JavaScript code at runtime. That is, there is no build step that takes your JavaScript code and converts it into Objective–C/Swift/Java/C#. Instead, JavaScript Native app frameworks utilize a JavaScript virtual machine to interpret JavaScript code, and to translate that code into the native APIs that build the app’s user interface.

Cross-compiled native apps

One final category worth mentioning is cross-compiled native apps. Cross-compiled native apps are similar to JavaScript Native apps, in that the language you write your code in is different than the platform’s native development language. For instance Xamarin lets you write iOS and Android apps in C#, RubyMotion lets you write iOS and Android apps using Ruby, and RoboVM lets you write iOS and Android apps using Java.

However, unlike JavaScript Native apps, cross-compiled apps statically compile your application code from the language it’s authored in to the language of the target platform. For instance, Xamarin iOS and Android apps are both written in C#, but a build step is required to translate that C# into native code that can run on each of the native platform.

Benefits of Each

Despite the invective you often see in much of the hybrid versus native debate, we’d argue that each means of developing a mobile app, including JavaScript Native, has its pros and cons. Each is best suited for certain kinds of apps depending on their specific requirements and/or the skillset of the developer(s) building them. Let’s take a look.

Hybrid

By its nature, hybrid has the benefit of targeting multiple platforms with, primarily, a single codebase. In fact, using Cordova, hybrid apps have the benefit of targeting the widest array of mobile platforms compared to anything outside of simply a mobile web site. Cordova currently targets eight platforms including Windows, Blackberry, FirefoxOS and FireOS. If those platforms matter to you, in addition to Android and iOS, then hybrid offers the easiest way to get there.

Partly because of this broad array of platform targets, hybrid also arguably offers the fastest route to market for a mobile app. This is particularly true if your team has strong web development skills but it’s supported by a number of mature frameworks such as Kendo UI Mobile (offered by Telerik), Ionic and jQuery Mobile to name just a few.

Additionally, hybrid offers the most opportunities for code reuse from your existing web assets.

Obviously, hybrid has suffered from perception of its performance, a view that wasn’t helped when hardware vendors chose to leave important performance enhancements out of the WebView available to hybrid apps (though, this situation has improved dramatically in recent releases). However, the performance implications are often overstated and are unlikely to impact a large number of applications — particularly things like internal business applications, where the fast iteration and skill reuse may offer the most benefit.

Native

It goes without saying that native offers the best performance of any of the options. Any form of abstraction, whether it be hybrid or JavaScript Native, will have some degree of impact on the performance of the application. So, for cases where every ounce of performance is critical, native may be the only option. The most common example of this, though certainly not the only one, is games, where a millisecond delay in performance can turn a game from enjoyable to needlessly frustrating.

Many developers might be saying to themselves, “What do you mean? Performance is always critical!” Well, that is true — to a degree. Think about it this way, the engine in a Formula One car theoretically performs better than the engine in a consumer car (at least from a speed perspective anyway), but this does not mean that consumer cars should start having Formula One engines. The performance of an application is as much about expectations and perceptions as it is about actual performance — and those expectations are often heavily dependent on the nature of the application you are creating.

We may be stating the obvious, but it’s worth noting that native offers the best possible means of gaining unfettered access to the all the features and capabilities of each platform. If you are building an application that needs to take full advantage of all of the capabilities of a particular platform (push the limits, you might say) then native is the way to go. This is enhanced by the tooling as that tooling is geared towards the specific requirements and needs of developing for that mobile OS (the painfully slow Google-provided Android emulator notwithstanding).

Of course, this is complicated by the need to maintain multiple codebases for a single app that targets multiple platforms. You may only really care about two platforms right now, which might make it less daunting, but it will obviously significantly impact the time and complexity of completing an app.

JavaScript Native

JavaScript Native apps are different because they challenge the conventional hybrid vs. native logic. Although the lines between hybrid vs. native were never completely clear, there were some guidelines you could give developers that were deciding between the two approaches. Need the very best performance and native user interfaces? Go native. Need to reuse web development skills? Go hybrid.

JavaScript Native frameworks complicate these guidelines, as JavaScript Native frameworks can offer performance that’s comparable with truly native apps, let you build interfaces with native UI components, and also let you reuse web development skills. For instance, React Native, NativeScript, and Appcelerator all use JavaScript for application logic (obviously), some form of CSS for styling, and npm for package management. React Native builds on top of React, which many web developers are already familiar with, and NativeScript has upcoming support for Angular 2.0.

Furthermore, the interpreted nature of JavaScript means that JavaScript Native apps can offer one of the web’s best features — a fast development cycle. This fast development cycle may be JavaScript Native apps’ most compelling feature, as it allows developers to develop apps with web-like refresh cycles, while interacting with native iOS and Android APIs and UI controls — something neither natively developed iOS/Android apps, nor cross-compiled native apps can offer.

For instance, in the video below I use NativeScript’s livesync feature to alter JavaScript and CSS that configures a UIButton and an android.widget.Button’s appearance:

In addition to this “live refresh” functionality, JavaScript Native frameworks also offer one compelling type of code reuse that hybrid apps don’t offer — the ability to use third-party iOS/Android libraries and SDKs. For instance, a number of popular services already offer iOS/Android libraries for integration — Google Maps, Facebook, Firebase, and so forth — and JavaScript Native frameworks have the ability to make these existing libraries trivial to use. For example, NativeScript supports using packages from CocoaPods, a popular iOS package manager, as easy as typing running the tns install command.

These various benefits, however, do not mean that JavaScript Native frameworks are a panacea for all mobile development problems, nor does it mean that JavaScript Native frameworks are appropriate for all development teams. For web developers taking the plunge into JavaScript Native development, here are a few of the hurdles you may hit:

  • JavaScript Native frameworks build native user interfaces, and although the frameworks abstract away many of the implementation details, it’s highly likely that you’ll need to learn a bit about how the native platforms work in order to build complex and performant UIs. This is not necessarily true in hybrid apps, as the UI is simply an embedded browser.
  • Memory management is far more important in a JavaScript Native app than in a hybrid app, as truly native objects are involved in building your application. In large JavaScript Native apps you may need to manage your JavaScript objects as you would in a compiled language.
  • The CSS-like implementations used in JavaScript Native apps aren’t the same as a browser’s CSS implementation. JavaScript Native apps take CSS properties and convert them into their native equivalents. For instance, NativeScript takes a background-color: red CSS rule, parses out the necessary values, and then sets a UIView’s backgroundColor property to an instance of UIColor. Because not all CSS properties have equivalents in iOS and Android, not all CSS properties are supported by JavaScript Native frameworks. Additionally, some CSS properties may be possible to implement, but are prohibitively expensive to apply to iOS or Android layouts without negatively affecting performance. Therefore, although web developers certainly get some skill reuse when using CSS in JavaScript Native apps, they don’t nearly as much they would in a hybrid app.

Cross-compiled native apps

The big advantage cross-compiled native apps can offer is the ability for developers to code in a language they’re comfortable with. For instance, if you’ve invested a lot of time learning C# in and out, then the ability to reuse those skills and build Xamarin-based native apps has a lot of appeal. Ditto building RubyMotion-based apps with Ruby, and ditto building RoboVM-based apps with Java.

Much like JavaScript Native apps let you use existing JavaScript utilities and libraries (usually from npm), cross-compiled native apps let developers leverage existing libraries from their respective ecosystems. For example Xamarin apps let you use existing C# libraries from NuGet and RubyMotion apps let you use existing Ruby Gems.

In addition to this code reuse, cross-compiled apps can also offer near-native performance, as the code that runs at runtime is true bytecode.

Conclusion – Knowing When to Apply Each

Developers have more choices than ever about how to build their mobile apps. As we discussed, each has its merits and its complications. To summarize:

  • Hybrid offers the quickest way to an app with the most code reuse, but has performance implications and a non-native UI.
  • Native offers the fastest performance and access to the full breadth of OS features, but has the complexity of maintaining multiple codebases and the need for developers with platform-specific development skills.
  • JavaScript Native frameworks offer some of the code and much of the skill reuse in addition to a web-like, fast development workflow. But, JavaScript Native apps don’t completely negate the need for platform-specific coding knowledge, and by targeting multiple platforms with a single codebase, some platform-specific features or styling may be unavailable or difficult to access.
  • Cross-compiled native apps offer developers the ability to use a language they’re already familiar with, as well as existing frameworks and tools from their ecosystem of choice. Cross-compiled native apps can also offer native-like performance, as true native bytecode is used at runtime.

At Telerik we strongly believe in choosing the right tool for the job, and we make products that support each of these development approaches. Building hybrid apps? We have great tooling to help you with the Telerik Platform, and a ton of useful Cordova plugins in our Cordova plugin marketplace. Building native apps? We have a suite of useful controls for iOS, Android, and Windows Phone. Building JavaScript Native apps? Our free and open source NativeScript framework can help you. Build cross-compiled native apps? We have a set of Xamarin controls that’ll help you build robust Xamarin apps quickly.

The trick is to understand the differences between these approaches, and choose the option where you can take the most advantage of the merits while being least affected by the complications. This will change depending on the type of application you are building, and the skillsets you and your team have. So rather than debating which option is better than the other, let’s embrace the opportunity that the array of options presents.

Header image courtesy of Chris Dlugosz

Comments

  • Pingback: Dew Drop – October 28, 2015 (#2121) | Morning Dew()

  • Gabor Dolla

    Cordova and React Native apps can be updated remotely, which I guess is an important feature.

  • Results of running Ringmark test suite created by Facebook years ago on my iOS 9 iPhone still looks pretty bad to me. Also, we are still to see large companies deploy successfully top quality Cordova apps that feel native. Angular 2.0 native support is vaporware. I think the only thing that really changed is React Native, which is too young to draw conclusions.
    Don’t get me wrong, I would like for the scenario to have changed and I do my best to contribute and find new ways of doing things. But your article is not bringing anything new. It’s just echoing exactly the same scenario from when Zuckerberg did that statement, with some React confetti on top of it.

    • remotesynth

      React Native is one small piece of a much larger set of solutions. React Native is young and draws the most buzz, but NativeScript, Fuse and others are making this a very competitive landscape for JavaScript Native.

      Angular 2.0 native support is coming. How can you dismiss it as vaporware when Angular 2.0 isn’t even out yet? Unless you are claiming Angular 2.0 is vaporware, in which case I’d say you are either misinformed or have an agenda to push.

      I fail to see how this echoes anything that Zuckerberg said. We’re not even talking HTML5 here.

  • Pingback: What To Expect From JavaScript In 2016  - Frameworks - Telerik Developer Network()

  • Shai Alon

    Good comparison TJ.
    In regards to the upcoming technologies, checkout a cool intro video to an open source Tabris.js starter template I made:
    https://www.youtube.com/watch?v=I8KHE6Yx7T0

  • Gaytri Dhatrak

    Cross platform mobile app development is in demand today. Many mobile app development companies provide cross platform mobile app development service. Here is one more informative material regarding Pros and Cons of Cross-Platform Mobile App Development http://bit.ly/2cr3ubP