ionic.zone - a site about all things Ionic

« Capacitor

    First published: March 2018

Introduction to Capacitor ⚡️

Capacitor is a way to create cross-platform mobile and desktop applications.

It can be used to package web apps made with HTML, CSS and JavaScript into native apps that work on Android and iOS (and can be uploaded to their respective app stores), desktop applications via Electron, and also Progressive Web Apps that run in all browsers - targeting all relevant platforms with one code base.

Capacitor itself calls apps built with its help “Native Progressive Web Apps”, meaning that they combine web apps that have characteristics of a Progressive Web App, with native functionality and code.

It is functionally pretty similar to Apache Cordova (formerly known as PhoneGap) which can be viewed as a predecessor to Capacitor but differs in some important areas and technology choices.

Capacitor is built in the open on GitHub as an Open Source project by the team behind Ionic, a “top open source framework for building amazing mobile apps”, where Capacitor it also intended to be used as a solution to build native applications.



Technical Overview

Capacitor wraps the web app in a so-called “WebView” that can display web apps inside the native app. It injects a “bridge” into the app running in the webview, that connects the code of the web app and the code of the native part so these can interact.

This way, functionality normally only available to native code can be used in the web app, and native code can interact with the web app running in the webview as well.

For Progressive Web Apps Capacitor provides fallback implementations to native functionality not present - like for example the default “Take a Photo” view on iOS and Android. It is rebuilt with web technology and provides a similar experience to browser users. This way the web app can provide functionality even when running in a normal browser, that is normally only available to native applications.

Capacitor achieves true cross-platform and portable functionality with 100% code sharing by providing a consistent API, @capacitor/core, to the web app. Any web app can integrate @capacitor/core as a normal import or even a “bundled web runtime” called capacitor.js that is just included via a <script> tag.

No matter if the app runs on iOS, Android, in a browser on a mobile device or normal computer - the provider of some functionality is always identical to the web app and all the complexity is taken care of by Capacitor in the background.

A much, much more comprehensive and deeper look at how Capacitor works from a technical point of view can be found over here.

Supported platforms

Native Progressive Web Apps built with Capacitor can be used on all the relevant platforms:

  • iOS
  • Android
  • Browsers: Progressive Web Apps
  • Desktop: Windows, macOS, Linux via Electron (work in progress)

Platform version support

Capacitor defines which platform versions are supported when creating the native project:

  • For iOS, it supports the last two iOS versions, currently iOS 11 and iOS 10.
  • For Android support starts at API level 21 which corresponds to Android 5.0 (Lollipop) or newer.
  • And on the browser side, all modern browsers that support Web Components (and actually many more via polyfills) will be able to display the web implementations.

Platform extensibility

Capacitor contains a fixed set of platforms that can be added to projects and doesn’t provide a system to dynamically load external platforms “definitions”. To add an additional platform, Capacitor has to be adapted and changed.

Supported native functionality

Providing native functionality to the web app is Capacitor’s main job. Because of that it includes a multitude of native functionality out of the box:

This list is currently still highly in flux as new APIs and plugins are added according to user feedback all the time. Missing anything? Go create an issue on GitHub.

There are also multiple ways to extend that functionality yourself: You can add custom native code to the native projects or install reusable Capacitor plugins or even existing Cordova plugins with npm.

Custom Native Code

The quickest way to add native code to your app is to write “local plugins” that are included in your native project. For both Android and iOS it is as simple as adding 2 files to your project to make native code accessible to the webview, which then can simply be called from the web app.

Capacitor Plugins

Capacitor also has a way to package these native modifications into reusable Capacitor plugins. Those can be published as npm packages, so other people can easily download and install them into their own projects. Of course, they can also provide their own “web fallbacks” so the plugins work in the browser in PWAs as well.

Cordova Plugins

As Apache Cordova has a flourishing plugin ecosystem (more than 3000 plugins actually!), the developers of Capacitor decided to also support Cordova plugins. Installation is a bit different as Capacitor doesn’t normally modify the native project files, but many plugins still work and can be used.

Command Line Interface

Capacitor CLI

Working with Capacitor is mainly done via its Command Line Interface, or CLI, called @capacitor/cli and executed via npx cap. It is used to create or init projects, add the native platforms and copy the web app or update plugin code to the native project. It is a local CLI bundled with each project, so different CLI versions in different projects are possible.

I also wrote a much more detailed Overview of the Capacitor CLI, @capacitor/cli.

Coming soon

While Capacitor already supports many of its planned use cases, in other areas there exist only plans and not much to look at yet:

  • Electron Support
    Already present in its infant stages in the repository now, Electron will enable Capacitor to build apps for all major desktop operating systems like Windows, macOS, and Linux.
  • Native UI Shell / Native Shell Add-ons
    The next step for even better apps will be to give developers powerful tools and ways to mix more native UI elements into their apps. A navigation bar built with HTML, JS, and CSS can look pretty much 99% like the real deal, but it will never cover all edge cases and most importantly never feel 100% native. Capacitor can and wants to fix this by popularizing new ways to mix native platform code with a web app, showing content. (See Basecamp’s David Heinemeier Hansson’s article about the “hybrid sweet spot” for more information about this idea)
  • Ionic Pro support
    Ionic is a commercial company and their main offering is a platform to build and manage applications built with Ionic. As Ionic until now uses Cordova under the hood, the whole platform is also built for that. It will take some time to adapt this and the connected code components to Capacitor.

Capacitor’s Relationship to Ionic

While Capacitor was started and is (currently) mainly built by Ionic staff, it is an Open Source project built on the philosophy to work with any web app - not just ones built with Ionic. Any web app that has an index.html file as its entry point can be packaged with Capacitor.

Ionic will probably add Capacitor to Ionic’s CLI as the default tooling for building native applications when Capacitor is stable enough and can support all the necessary use cases that are currently covered by Apache Cordova.

Consequences for Apache Cordova

Ionic Framework is one of the, or the, most popular “user(s)” of Apache Cordova. Each developer packaging their Ionic app as a native app installs Cordova via npm install -g cordova and uses it to build the native iOS and Android apps with ionic cordova build ios|android - so the download numbers of Ionic and Cordova are tightly coupled, and Ionic contributes quite a lot to them.

Capacitor CLI

But Cordova was started almost 10 years ago, was still called Phonegap back then, and a lot has changed in the meantime:

It became clear which native platforms are here to stay (not Palm webOS, tizen, FireOS, Blackberry, Firefox OS or Windows Phone - which Cordova all supported at their time), what native functionality all the remaining operating systems offer their users and which of these the users actually want to use. It also became apparent which problems the choices made by the early Cordova developers were causing for developers today.

The biggest change only happened in the last few months when mobile and desktop browser got better support for Progressive Web Apps and Web Components got standardized and implemented. This enabled browsers to become their own, proper platform to be considered to roll out apps. And Cordova is just not set up to support this.

That being said, Apache Cordova of course will not go away - in general and also in Ionic CLI. Capacitor might become the “Successor to Cordova”, or it might just become an alternative for slightly different use cases.

Comparison between Cordova and Capacitor

To understand better why Ionic decided to build Capacitor instead of building further on Cordova, it makes sense to take a deeper look at: The differences between Capacitor and Cordova. (To summarize: No global CLI, built-in PWA and web support, but also technical details like the non-existence of a deviceready event the app has to wait for.)

Some more details

While not the most important developing facing features, there are some more very interesting details worth to know about Capacitor:

Native projects are source artifacts

In Capacitor the native projects it creates and you customize are treated as so-called “source artifacts”. That means that once a project is created, you keep it an check it into source control. Capacitor will not (or as little as possible) mess with it anymore, so it is a fully independent piece of code.

Use whatever language you want

Capacitor is built with Swift on iOS by default, but Obj-C can still be used for plugins and custom native code if you want to. Android is all written in Java, but Kotlin is also supported if that is more your style.

Monorepo

Capacitor is structured as one big “monorepo” which contains all the parts (@capacitor/cli, @capacitor/core, the native libraries for iOS and Android, a development project, the plugin and platform templates, even the website and docs) versus one repository for each component or part of the whole solution, as many other highly complex libraries like Cordova are organized.


Did I miss anything? Let me know in the comments below and I will update the article as quick as possible. Thank you.


« Capacitor

    First published: March 2018