Tech Hub

Mobile App Development

Capacitor Early Look

A Modern Native Web App Bridge

The Ionic team announced a short while ago that they were working on a project named "Avocado," which later took on their official Capacitor name.For now it's easier to think of Capacitor as a variant of Cordova owned by the Ionic team.

Capacitor is not just applications for Ionic. To make Capacitor work with an existing project, all you need to do is provide it with the path to the web code that you want to bundle into the native application, so it can work with just about anything. Capacitor's philosophy seems to be to integrate easily with whatever build configuration you already have, rather than integrating your existing projects into Capacitor.

What is Capacitor?

Capacitor is a cross-platform app runtime that makes it easy to build web apps that run natively on iOS, Android, Electron, and the web. It was created -and is maintained- by the Ionic Framework team.

Capacitor can be viewed as Cordova's own version of the Ionic squad. If you were to use Capacitor, you would use it to add native features to your mobile web-based applications instead of Cordova. Unlike Cordova, the connection between the client and the computer will be Capacitor. The website of the Capacitor describes very succinctly its objectives: Native Progressive Web Apps. Capacitor wants to be a runtime layer that enables you to build and run an application anywhere (even if you implement native code).

Capacitor's existence doesn't mean anything is happening to Cordova. Cordova is the Apache Software Foundation's project–it is its own organization and will continue to exist and work as it always has.

Of course, their own version of Cordova is not built by the Ionic team just for the fun of it. Capacitor has many worthwhile aims, and for Ionic applications will ultimately become the choice over Cordova. The Ionic team, however, said they're going to continue to support Cordova.

Instead of creating a new native bridge, the Ionic team might have decided to build the features they wanted in Cordova, but ultimately decided they would need full project control to best execute their vision. It is not an easy task to make big sweeping improvements to a well-established and mature system.

What will Capacitor do differently to Cordova?

When developing cross-platform applications using web technology, the biggest source of friction is often the native bridge between the browser and the device, a role typically filled by Cordova. This is the crux of the whole "hybrid" approach to building mobile apps, so it makes sense to often consider the friction here. It also makes sense that this is an area with enormous potential for improvement.

So, what is the Ionic team planning to do to improve this? There are a few aspects that especially stand out for me:

PWA Compatibility.  For Modern Web Applications, there has recently been a huge movement. They are beginning to receive more browser support, and more tools are beginning to pop up to help people build PWAs. One cool thing about a PWA is that it can easily be bundled as a native application as well as access native features (using Cordova / Capacitor). But, when running as a PWA through the browser, native code won't work. This can make it difficult to maintain a single codebase for a project to be deployed as a native application and as a PWA (and likely also as a desktop application). With Capacitor as the runtime layer, any errors that arise can be handled gracefully.

Ease of native controls integration. Capacitor aims to make it easier to include controls on the native user interface wherever you want. For instance, if you wanted to use a native menu to create that interface instead of using the browser.

Native functionality is immediately available. You need to wait until the system is ready to make calls to native features when using Cordova (e.g. using platform.ready). Capacitor must export JavaScript to the boot of the system to avoid this.

Plugin support. All native features are accessed via a plugin. You use the camera plugin if you want to use the camera. If there is no plugin available to do what you want, or if it is available but it is not maintained, you will be somewhat out of luck unless you know how to build the plugin yourself. Capacitor aims to facilitate the process of plug-in creation and maintenance.

Redesigned plugins. Capacitor will include a core set of plugins that will be maintained by the Ionic team (Camera, File API, Geolocation, etc.). They plan to redesign these plugins in order to solve some common problems (such as the difficulty of using the File API, and how Android Geolocation works).

Setup localized. Capacitor will be installed locally in projects, which means that multiple versions between multiple projects will be easier to maintain.
Although Capacitor operates quite differently from Cordova, as many Cordova plugins as possible are still aimed at backward compatibility by the Ionic team.

 

Using Ionic System Capacitor

Now that we've been talking about what Capacitor is, let's build something! Here you can find a project to start a Capacitor. You can clone this and set up a Capacitor project like this, but we will add Capacitor to an existing Ionic project. We're only going to create a blank Ionic project and add a simple call to the plugin for the camera.

Capacitor uses the npx command, available only in version 8.6.0 or higher of the Node.

If you plan on building for iOS, you will also need Cocoapods installed (a dependency manager for iOS projects). If you do not already have it installed, you can just run the following command:

sudo gem install cocoapods

1.Create a New Ionic Application

We'll just use a blank Ionic project to add Capacitor to it:

ionic start capacitor-myapp blank

Do not integrate Cordova into the project when asked. Make it your working directory once it's finished installing:

cd capacitor- myapp

2.Add Capacitor to the Project

Finally, by design, Capacitor will be incorporated with the Ionic CLI, so you don't have to think about these set-up steps. For now, setting up Capacitor is still easy enough. Next, a file named capacitor.config.json needs to be added to the project's root folder:

capacitor.config.json
{
  "bundledWebRuntime": true,
  "webDir": "www"
}

It is important to add the webDir property as this is where Capacitor will search for the web code to bundle into the application – it is set to "public" by default. The following dependencies must also be added to package.json (do not remove existing dependencies):

"dependencies": {
    "@capacitor/cli": "latest",
    "@capacitor/core": "latest"
  }

and you will need to add the following under "scripts" (again, don’t remove the other entries):

"scripts": {
    "capacitor": "capacitor"
  },

Once you have made these changes, the new dependencies must be installed by running:

npm install

To add native platforms that you are targeting you can run the following command for iOS:

npx capacitor add ios

or for Android:

npx capacitor add android

Now you'll see android and ios directories in your project's root folder. This is all you need to get your application to set up Capacitor. It assumes that you already have the correct building environment on your computer for iOS / Android (i.e. you have been able to create Cordova builds successfully before). If you don't have XCode / Android Studio on your phone, the Ionic team will be able to follow this guide..

3.Use the Camera Plugin

Now we'll just look at a very basic example of Camera plugin integration. For the Camera plugin and other plugins, you can find documentation here. All we need to do is import the plugins from @capacitor / core to access a plugin from Capacitor:

import { Plugins } from '@capacitor/core';

And then the plugin we're interested in can be accessed. If we wanted to set up a feature that would allow a user to capture a picture from the camera or the photo library of the user, we could do this:

import { Component } from '@angular/core';

import { NavController } from 'ionic-angular';

import { Plugins } from '@capacitor/core';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
	constructor(public navCtrl: NavController) { }
 
	grabPhoto() {
    	const { Camera } = Plugins;
        Camera.getPhoto({
        	quality: 100,
        	resultType: 'base64'
        }).then((result) => {
            console.log(result);
    	}).catch((err) => {
            console.log(err);
    	});
	}
}

This would take the photo and return it to us in the format of base64. It is important to include the catch statement here because if we don't and try to run this application as a PWA we will get the following error:

ERROR: Uncaught (in promise): Plugin does not have web implementation.

This example will now work seamlessly across multiple platforms. The concept of having plugins not break the web-based implementation of the application is not new, this was something we could do with Ionic Native/Cordova as well, this is just one of the things that the Ionic team wants to make easy with Capacitor.

NOTE: As Max has pointed out in the comments below, the Ionic team do intend to build out web implementations of these plugins. So, in the above example you could actually use this plugin and have it provide you with a nice camera interface even when running as a PWA.

4. Build the Application

We have an application using Capacitor, and we have an example of how to use the Camera plugin, now we just have to deploy it to a device. Capacitor works with whatever your existing environment is. So, you just do whatever you would normally do to produce a production build.

In the case of Ionic, the following command can be used to construct a production build:

npm run ionic:build --prod

This will create a production version of our code in the www directory, which is the directory we told Capacitor to get the web code from earlier. Now you just need to copy this web code into the iOS and Android projects that you created earlier. For iOS you can run:

npx capacitor copy ios

and for Android you can run:

npx capcitor copy android

Then to build the applications, you once again just build it the way you would with a normal iOS/Android project. If you were to run the following command:

npx capcitor open 

Then pick ios to run the program within XCode. You can just hit the play button in the top left corner from there to create then run a build of your application.

Summary

While there's already a lot of codeshare with how we build Ionic applications today, with Capacitor Ionic's introduction it really seems to make the one codebase, all platforms dream of a literal reality. This project will make the deployment of a single codebase as a Desktop / Web /iOS / Android framework far easier.

As you might say, this isn't a big scary move that will totally change the way you create your devices. Once Capacitor is ready for production, most people will probably look at some simple changes in syntax if you choose to use it.

Share Linkedin