Technologies for building mobile apps

Teodor Sandu
Adaptabi
Published in
11 min readAug 15, 2016

--

In our research we found several articles investigating native vs. hybrid vs. mobile web apps, but we couldn’t answer a key question: what technology do we recommend to a client given a mobile project idea? To answer we need at least a general understanding of the main options, then to find the relevant questions that we have to ask our client or ourselves before going one route or another. So here at Adaptabi we aim for the communication with a client to boil down to this process:

How we aim to recommend mobile app technologies for future projects

The first question is if the project needs to present users with the same, personalized look and feel no matter if they’re using an Android, iOS or Windows Phone device (Same UI?). If not, which means users should get a native look and feel depending on their platform, then we find Cross-platform apps to be a very good candidate. Xamarin allows us to reuse our C# skills, and React Native or NativeScript are based on Javascript and are capable of the very powerful Hot Code Push mechanism.

If the same UI is desired across platforms, then we need to analyze overall complexity and performance requirements. In most cases, a Hybrid app is up to the task and benefits from an accelerated development speed over Cross-platform apps. However, if performance is paramount and we detect that Hybrid apps may reach their inherent limits, simply being unable to run smooth enough even after most possible optimizations, then Cross-platforms apps can certainly get the most out of the underlying system. In theory, Xamarin is also faster than React Native or NativeScript because it compiles directly to native code while the latter have Javascript code interpreted in a background thread, which makes them run a tad bit slower.

Let’s start by examining our conclusions and thought process. Take a look at the table below. We’ll explain everything.

DISCLAIMER: when we say “bad” or “slow” we don’t mean it’s absolutely bad or slow. It depends on the current situation. For example a “bad” UI is only bad if the project demands a very complex interface that runs smoothly. If not necessarily, then it can very well be the ideal choice. Development costs are also taken into account.

These are the criteria we’re using to assess our options:

  1. Same UI/UX — when the user interface must look and feel exactly the same across all platforms. UI performance (responsiveness) included.
  2. Native UI/UX — when you must provide users with a familiar experience on the platform they’re using. UI performance included.
  3. Performance — business logic / processing performance, not UI performance.
  4. Development experience — tooling, learning curve, ability to efficiently debug your apps — these translate into upfront development time and ongoing development and maintenance costs.
  5. Build/Deployment — each technology type comes with its own features and constraints/challenges when delivering the app to your users.

Mobile web apps

These are regular web apps or websites with a mobile-optimized or responsive UI, running in the device’s native or user-installed browser. Configured properly it can allow users to create a shortcut to it on their homescreen, which will open the web app in a full-screen system browser window, thus allowing you to imitate a native app.

Same UI/UX: bad

The common pitfall is thinking that if you have a responsive-layout web app that looks good on desktop browsers, you’re all set. Wrong. Mobile browsers have many quirks and differences in CSS and even JS support, which makes even medium complexity UI’s an absolute pain to develop and the JS needing multiple poly-fills which end up costing initial load time and bandwidth.

UI performance plummets once you exceed a certain number of elements on the page, and while there are numerous optimizations possible, it’s very costly to apply them consistently across many mobile browsers.

Native UI/UX: bad

Obviously, trying to replicate the native Android or iOS UI’s in any browser is a very bad idea, since you can’t get the same responsiveness and feel and you’ll end up in the uncanny valley.

These being said, mobile web apps get a “bad” in both UI criteria. However, if the UI is extremely simple and/or you plan ahead (maybe start simple then move to a hybrid app once the project grows more complex), then this is by far the fastest way to start a project. For example if the client already has a web app then setting up an “m.something” domain, a login and a couple of the simplest features may take less than a week to complete and the client sees something fast. But it’s very important that you both understand the inherent implications.

Performance: slow

“Slow” only means “slower than native” when it comes to performance. Usually this is fast enough, but it can fall short when you really need to get the most computing power out of the user’s device. Also, if not used correctly it can block the UI thread and make the interface unresponsive for unacceptable periods of time. This adds complexity to your code since you need to mind the UI when you’re doing time-consuming operations.

Development: good

The development experience is as easy as it gets. You have all the bells and whistles at your fingertips with Chrome debugger, ADB to inspect apps running on Android devices just like on desktop, same thing for iOS devices with Safari, etc. If you’ve been developing web apps, it’s clear why mobile web apps are the fastest to start with. Until you hit the UI or performance snags.

Build/Deployment: good

Deployment is a no-brainer, it’s basically a website. New users will always get the latest version. Existing ones will get it at page reload, an action that redirects or refreshes the page, or at their next visit.

Conclusion

Mobile web apps may be appropriate in some cases, like a proof-of-concept or a test app to see if users are interested. Be careful what you’re committing to, and thoroughly explain to your client that this app will never go far. Most probably it will need a full rewrite very soon if the project grows even a bit past website capabilities.

Never blindly assume that if something works in desktop browsers it will work on mobile browsers too. HTML5 API’s have inconsistent support, yet progressive web apps may be a solution. Take them with a pinch of salt though, since if some feature is not supported in some browser, usually there’s nothing you can do about it.

Native apps

These are written in each platform’s native language and draw their interfaces via native controls, thus ensuring a consistent UI across multiple apps on the same platform. See Material Design and iOS Human Interface Guidelines for example.

Same UI/UX: bad

Of course trying to make an Android app look and feel like an iOS app or vice-versa is a bad idea, because UI metaphors differ and your users will get confused.

Creating a custom interface across platforms is a very good way to go, but it costs more development time than taking advantage of the existing platform-specific experience. If the client is fine with it or the project really demands maximum UI performance and the same interface across platforms, then change this section’s evaluation to “good” and proceed.

Native UI/UX: good

Well, “best” actually. You can brand the app to make it have your custom design but have the platform-specific experience that users are accustomed to. Settings screens will feel natural and so on.

Performance: fast

Again, “fastest” actually. Native apps are closest to the underlying OS and hardware, thus when in need of processing power this is all you’ve got.

Development: bad

Don’t get us wrong, writing Android apps is a good development experience, as well as iOS or Windows Phone. However, there are 3 different apps to create and maintain, which add up to the costs.

Build/Deployment: bad

Normally this should have been “good”. But if an Android release usually takes a few hours, an Apple store release can take up to a couple of weeks. Now imagine breaking changes on the server side and the associated versioning costs of API, database structure or even actual data.

It’s not that these difficulties can’t be addressed, they can, and in a very stable and consistent manner, but they take quite some time. And since Hot Code Push made it’s way into more and more applications, they are easier to be avoided than ever.

Conclusion

Native apps are fastest, have the most responsive UI possible, and integrate best with all device features. However, having separate development environments, creating and maintaining multiple apps is very costly.

Hybrid apps

A hybrid app is composed of two individual apps. A mobile web app like the one above, which ensures a single code base and a consistent user experience across platforms, is being loaded inside a webview component (just like a browser window in full-screen mode) of a native app, typically Cordova. This native app acts as a container, and provides (along with a large number of Cordova plugins) a Javascript API for the mobile web app to access device features like camera, sensor data, GPS, filesystem and so on. This makes device integration equivalent to native apps.

Historically these containers would use a native webview component (like the stock browser for example) to render apps which would make hybrid apps experience all the UI issues as a regular mobile web app. However, on Android Crosswalk minimizes these issues by using a very well performing Chrome based webview component across Android versions. Since iOS 8 the equivalent solution is WKWebView.

Same UI/UX: good

Since it’s a web app, it’s easy to create the same experience across platforms. This leads to good development speed and UI consistency. Minor differences occur when choosing a file to upload or opening the camera (i.e. launching native behaviors), but those are expected by users so they won’t be easily confused.

UI performance is very good up to a certain complexity. Although it will never match native performance, this technology is mature enough to ensure good UI responsiveness and a fluid user experience if it doesn’t block the UI thread with time-consuming operations.

Native UI/UX: bad

Obviously, trying to replicate a native look and feel you will end up with separate interfaces to build and maintain for each platform. And because you can’t match native performance it’s very likely that metaphor trade-offs will lead your app into the uncanny valley.

Performance: slow

See the performance section on Mobile web apps. The same considerations apply here as well, but hybrid apps have a way around some limitations. When CPU intensive operations are needed their execution can be passed on to native components, like a custom Cordova plugin which provides its API for the mobile app to invoke methods and receive the results. However, building and maintaining a native plugin requires extra development effort and interferes with the deployment process, which is why it’s preferable, as long as it’s possible, to avoid custom plugins.

Development: good

Being a mobile web app it’s very easy to work with, and tooling is abundant. The only overhead is the native app, which needs to be installed first and needs a little configuration. Live code reload makes the development experience even better.

Build/Deployment: good

Hot Code Push is an extremely powerful ability. It allows you to release the native app in stores once, then use a server to deploy fixes and features (by updating only the mobile web app code) while bypassing store review. This is a legal shortcut as long as it doesn’t change the declared purpose or overall design of the app. It works by having the native app connected to the server which holds the mobile web app files. When an update is available, the native app downloads the mobile web app code, replaces the current files and simply reloads the page in its webview component. It also triggers events so if the app is currently running you can ask users if they want to update right now or later.

App store updates are still needed, when either the native part of the app changes (e.g. to add a new plugin or update native code) or the app no longer corresponds with screenshots (e.g. after major design changes). But these updates are usually rare, which allows a rapid deployment cycle, a smooth in-app update experience and users having the most recent version as soon as possible. It can also help mitigate server side versioning complexity by ensuring that the mobile app is always up-to-date.

Conclusion

Hybrid apps are a very compelling solution. They provide tight device integration and performance via native plugins, rapid development and deployment cycles thanks to great tooling and hot code push, and a fluid, consistent UI and user experience across platforms.

Cross-platform apps

These apps are written once in one language, then compiled into native apps for each platform. For example with Xamarin you write C# code which gets compiled into truly native apps for Android, iOS and Windows Phone starting from the same codebase. Well, the same codebase for the business logic. The UI, once it exceeds a relatively low complexity threshold, is best coded separately for each platform, but still in C#, which is very good if you’re comfortable with the Microsoft environment. Other than this, all native apps considerations apply (notably the deployment ones).

React Native and NativeScript are Javascript cross-platform apps which achieve the same thing but there’s a crucial difference from Xamarin: these apps actually interpret the JS code in a background thread and render it using native components (sort of like a hybrid app with a special webview that instead of rendering HTML tags, renders native buttons and other UI components). This allows for Hot Code Push capabilities, which is no small feat.

Same UI/UX: bad

Native apps considerations apply here as well, so it can be “good” depending on the project.

Native UI/UX: good

Using native controls ensures a truly native experience. UI performance is very good as well.

Performance: fast

Well, Xamarin is fast. Since it compiles to native code, it’s as fast as native apps. Again, the lack of Hot Code Push is the only downside.

As for Javascript cross-platform apps, they’re faster than hybrid or mobile web apps because their code runs in a separate thread than the UI thread. The communication between Javascript and native code is also faster here, but they’re still slower than their native counterparts. So if maximum performance is needed, then the same reasoning from hybrid apps can be employed.

Development: bad

While business logic code can be reused, UI code typically needs to be implemented separately. NativeScript aims to fix this, but we’re not big fans of their holistic approach simply because it can quickly get more complicated than we bargained for once we dive deeper into tweaking native components.

Also there is a pretty steep learning curve, but it’s easily worth it if the project needs it.

Build/Deployment: good/bad

As you surely guessed, Xamarin gets “bad” because it generates native apps (so native apps considerations apply), while Javascript cross-platform apps get a very “good” thanks to their Hot Code Push capabilities.

Conclusion

Cross-platform apps are quickly becoming an important contender to hybrid apps with the advent of Hot Code Push. They are fast, have native UI’s and a smooth user experience, and business logic code can be reused. Also, we can write them in Javascript which is just great.

Summary

We hope this article gave you some insight into the kind of thought process required when choosing the right tools for your next project. Communication with the customer is key, and it’s up to you to thoroughly explain all the pros and cons, upfront and ongoing development and maintenance costs, etc.

Remember, any feedback is good feedback, so we’d love to see what your thoughts are on this matter.

Thank you for reading!

--

--