January 2023 Note: This article is quite old, and still references UIWebView. Today, Capacitor uses WKWebView and modern web view controls. The rest still applies.
Clickbait title! Cue the backlash. How dare he?
Every single app in the app store is made up a collection of native controls. Some use these controls exclusively and use the standard SDKs and programming languages pushed by mobile vendors, known by adherents of this approach as pure native apps. Some use the stock native controls but eschew the standard programming languages, becoming less pure in the eyes of devotees.
Still others use a few native controls and some of the native development stack, but push more of the work of the app into an abstract web layer using a Web View. Such apps might use this for a login flow, for content they wish to update from the server, or for a majority of the UI. Many developers call these “hybrid” apps and the native devout consider them truly profane.
Cordova/Capacitor apps are in the latter category. Why? Because there are benefits to abstracting away your app to the web layer. That code can now run on a variety of platforms with few changes, can be worked on easily by the plethora of web developers in the market, uses standard web development libraries and techniques, and can be built in a very rapid fashion. The web runs in a lot of places and developers often enjoy targeting that runtime.
Users today are happy with either approach, assuming the developer put in the same level of polish they would for any major product for their business. They’re happy with them because they have the exact same capabilities and phones can handle the abstraction of the web better than they could before.
If it quacks like a duck
So, Cordova or Capacitor apps can still do everything a native app can. How? Because they’re native apps, too!
Here’s a view hierarchy of what a stock Cordova or Capacitor app looks like on iOS (this is Cordova, specifically, but Capacitor is somewhat similar):
Notice something? Those are all native controls and views. We’re running in a native app, we’re just doing a lot of work in that pesky UIWebView. And, because we’re a native app, we can easily use native controls. Here’s what happens when we pop open an native Action Sheet:
So, our “hybrid” app is doing things a “pure” native app would do. Seems pretty native to me.
Some might say I’m being facetious: “it’s not a native app unless the app uses the stock controls Apple blesses.” I get that argument, but then explain how apps like Snapchat get a pass, despite the large amount of custom UI that doesn’t fit what Apple handed down from the heavens as the One True mobile UI? It’s okay because it draws rectangles on UIView instead of drawing rectangles on a div in a web layer? What about traditional native apps that use a large amount of web content in the flow of the experience? Is that okay as long as it uses UINavigationController with no customization? What about Cordova/Capacitor apps that have native code or mix web and native in large amounts?
Where does it end?
All the same to users
I’m proud that Ionic apps are hybrid, I think it’s a wonderfully productive blend of the best of the web and the best of native. I’m also a fan of the native development stack and regularly build native plugins and apps with Swift and Java.
However, we have to understand that end users don’t know the difference between a “hybrid” app and a “native” app, just like the millions of us that use Slack for desktop 24 hours a day without caring or even knowing that it’s built with Electron.
To end users, a native app means they can find and install the app in the App Stores. They can run it on their phone instead of opening a browser. The app works offline, stores their login session, can take pictures and do things that Safari just can’t yet on its own.
A Cordova/Capacitor app and a classic native app all have those exact same features and benefits to users. Additionally, both are cryptographically signed binaries created using the exact same publishing process. The payload in a Cordova/Capacitor app has more web than a classic native app, but it’s still a native app binary ready to be distributed to the app store.
To end users, “hybrid” apps like those created with Cordova/Capacitor (and Ionic Framework) are native apps. Why are we so afraid to call them that?