Should you transpile your cordova app?
Tags: webdev, cordova, mobile, babel
Published: 2019-08-15 00:00:00

---
date: "2019-08-15"
title: "Should you transpile your cordova app?"
published: true
category: "Cordova"
tags: "webdev, cordova, mobile, babel"
cover_image: "https://thepracticaldev.s3.amazonaws.com/i/pjgtwe6nbbg3z3houmzk.png"
canonical_url: https://www.learningsomethingnew.com/should-you-transpile-your-cordova-app
---

The following is based on a true story.

## Just worst
You've finished your amazing cross-platform mobile app, you publish it on the stores, and then you get this review:

![bad-review1](https://www.learningsomethingnew.com/cordova-babel/bad-review1.png)


Hmm.. But it opens on my phone! So you take a closer look:

![bad-review2](https://www.learningsomethingnew.com/cordova-babel/bad-review2.png)

Oh right, we never checked it on an old phone. Darn. Let's try it on an Android 4.4 emulator:

![error](https://www.learningsomethingnew.com/cordova-babel/bundle-js-error.png)


So a quick search of some of the errors points to the problem. We used all the cool new ES6 syntax, but the WebView is too old to support ES6.

## How likely is this to happen? What's the impact?

So your app that uses ES2015+ syntax doesn't work on old devices. But how old? And how many?

In order to assess the damage, we need some data. We're basically asking what's the adoption rate of new browsers **within the system WebView components of Android and iOS**. But what browser does the WebView actually run? This differs by the OS and the OS version, so let's look at both major mobile operating systems.

### 1. Android
The WebView cordova apps use in Android is the system WebView component. There have been two major changes in how the Android WebView works in recent years:
1. Since Android Lollipop, the WebView [auto updates through the app store](https://developer.chrome.com/multidevice/webview/overview#will_the_new_webview_auto-update_). So a device running Android 5.1 will support new ES features (as long as the user actually approves updates of the WebView app).

2. Starting from Android 7 (Nougat), [Chrome and WebView are the same](https://developer.android.com/about/versions/nougat/android-7.0#webview). That means the WebView cordova uses is the same version as the Chrome app, and there is no need to update a "System WebView" app. 

> If you're bored, check out some of the reviews of the "System WebView" app on the play store:

![webview-review](https://www.learningsomethingnew.com/cordova-babel/webview-review.png)

For Android versions **below L**, the WebView is part of the OS and won't update without updating the OS.
Looking at the market share numbers of Android versions, we see that we don't really need to worry about Android versions below L, as they make about ~3% of all devices:

![android-versions](https://www.learningsomethingnew.com/cordova-babel/android-versions.png)

If you still want to cater to this ~3%, or your app runs on specific proprietary devices that can't be upgraded, then you have two options:
1. Transpile all the way down to chrome version 30 (or lower if you need to support below Android 4.4)

2. Use the deprecated crosswalk plugin which ships the WebView *within your apk*. It's no longer maintained (because the changes mentioned above render it quite useless), and doesn't install at all if you use the new cordova CLI (version 9). If you really have to support old devices, I've managed to find one [fork](https://github.com/waitaction/cordova-plugin-crosswalk-webview.git) of the project that actually works with new cordova versions, but it will probably stop working with the next version :)
 
### 2. iOS
iOS 8 and Yosemite introduced the new WKWebView, which now deprecates the old UIWebView (read more about it in this very detailed [post on nshipster](https://nshipster.com/wkwebview/)). The new WKWebView runs the same JS engine as Safari, so that's basically the same change that Android 7 did with Chrome and the system WebView.

Notice though that in new cordova projects (version 9 currently), cordova still uses the old and deprecated UIWebView, so it's recommended to upgrade to WKWebView in new applications. More about this in this [announcement by cordova](https://cordova.apache.org/news/2018/08/01/future-cordova-ios-webview.html)

So if we're using WKWebView which was introduced in iOS 8, how many users are we losing? According to this, less that 2.3% (version 8 isn't even listed):

![ios-versions](https://www.learningsomethingnew.com/cordova-babel/ios-versions.png)

As you can see, the problem is less severe with iOS than with Android. This is a perk of having the same company that makes the OS also make the hardware.


### How to transpile
We can't talk about transpiling without talking about babel.
From the babel [docs](https://babeljs.io/docs/en/):
> Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments.

It's a pretty cool project, which lets us use the newest language features before they get adopted into all browsers. But you'll notice that the babel configuration is non-trivial to say the least.

Luckily, most frameworks come pre-configured with babel these days, so if you generate a Vue CLI 3 app for example, it will come with a configuration of webpack to use babel.

If you're messing around with a newer / less known framework, try to find a sample project on github that has the babel configuration.

> If you're using Svelte, you can check out my post on how to configure babel with rollup for a svelte cordova app [here](https://www.learningsomethingnew.com/how-to-make-your-svelte-cordova-app-work-on-old-phones-using-babel).

## So, should I transpile my cordova app?
Yes you should. It's the same argument for why you want your web app to be transpiled (down to the last two versions of major browsers is a good standard, but it depends on your app's customers).

As a developer I always like to use the latest language features, and I can never be sure what my end customer's browser will support. I don't think it's a good idea to stay behind and just use the language features that are already widely supported. Language improvements make development faster and our code better. Luckily, you can use babel's [preset-env](https://babeljs.io/docs/en/babel-preset-env#targetsbrowsers) and define your target browsers generically using a query to select browsers (ex: last 2 versions, > 5%, etc).

If babel ensures our code runs on the last two versions of all major browsers, and we know the vast majority of Android and iOS WebViews are updated automatically as part of the OS, then we're pretty much 99% covered. 

Finally, here is a decision tree to help you decide:

![decision-tree](https://www.learningsomethingnew.com/cordova-babel/decision-tree.jpg)