Capacitor – Invade the mobile world with just HTML, CSS, JS

Tram Ho

You are a tech lead specialized in web but suddenly one day you are forced to deploy products for mobile platforms in a short time? Or is a front-end/back-end/full-stack web dev looking to move into mobile but don’t know where to start? Or do you have a unique idea for a mobile app that you can earn but only know HTML, CSS and JS? Or are you just a lame skeleton, want to explore and expand knowledge but have limited capacity, can’t cram many things like me

Capacitor is the solution for us. Let’s learn about Capacitor and the advantages it brings to web people in developing a mobile application through this article.

Disclaimer: Capacitor is just one of many solutions to help developers have many options to solve problems depending on requirements, cases, circumstances and resources. So in this article, I only focus on introducing and guiding on Capacitor, not pointing out the advantages and disadvantages compared to similar solutions like Cordova, PWA, or React Native…

A little theory

capacitorjs.jpg

A cross-platform native runtime for web apps.

A cross-platform native runtime for web applications??? Wtf??? Reading English is difficult to understand, but translating it to sound both bananas and more difficult to understand. But that’s the big text right on the homepage to introduce Capacitor , a product of the Ionic platform by the duo Max Lynch and Ben Sperry co-founder and developer. Simply explained, Capacitor is a tool that allows developers to build mobile applications on Android and iOS with only basic web technologies such as HTML, CSS, JS, or higher, Angular, React, Vue…, or higher, Nextjs, Nuxt, Quasar…

Working mechanism

This paragraph I also only partially translated from Max Lynch’s blog post, you can read his blog post directly to understand better here .

How capacitor works - basic

Basically, Capacitor is a bridge that helps web applications written from HTML, CSS, JS to run and communicate with mobile platforms such as Android or iOS. Going a little deeper, you can see that the Capacitor includes the following components:

How capacitor works - advanced

In the diagram above, please pay attention to an important component, the Web View , which is an integral part of the Android and iOS operating systems. Web View allows web pages to be displayed like a web browser, so web apps should work just as well. Taking advantage of this, Capacitor encapsulates our web app in a Web View, which then acts as a bridge to interact with “native” features (i.e. OS-specific features, for example to open a dialog, Android will have a different implementation, iOS has a different implementation), when you need to use a feature, just call that feature through the API.

For those of you who have experience in the mobile field, it is probably no stranger to this model, this is also known as the Hybrid application model.

With the above method, we can develop mobile apps for multiple platforms with just one codebase written in web language, with any web technology the team has chosen, or even a finished web app. It is still possible to integrate Capacitor to become a mobile app without having to change much about the codebase.

Plugin Ecosystem

As mentioned above, the “native” features of mobile are “bridged” by Capacitor so that our web app can call at any time through the API. Native features exist as “plugins”. For example, my app needs vibration function to interact with users, I can install Haptics plugin, then from JS code call Haptics.vibrate() to vibrate the user’s device. It’s too simple.

In addition to Haptics, there are many plugins developed by both Capacitor’s core team and the dev community so that we can use them right away. You can see the list of plugins as below:

These plugins are actually written in OS-specific languages, for example, for the Haptics plugin, to build the Haptics.vibrate() device vibration API, the Capacitor team had to write both languages ​​for the two platforms. platforms are Android (in Java) and iOS (in Swift) as you can see at this github repo . Thought it was simple but not simple, but rest assured, 99% of the cases the available plugins are enough to serve our needs, the remaining 1% is too difficult to ignore . Create your own plugin

In addition, in that 99%, there are also plugins from Cordova, Capacitor is designed to be compatible with many Cordova/PhoneGap plugins (Capacitor’s predecessor, the same idea and application of the Hybrid apps model). Installation and use are also relatively simple. What’s more convenient, since most of Cordova’s plugins are written in JS, the dev community also builds TypeScript wrappers that are gathered in this repo , making these plugins even easier to use and transparent.

Turn web app into mobile app

Here I choose a random web app To-do list on github:

Capacitor todo app demo

This App has been fully coded with basic functions, now I try to integrate Capacitor to turn it into an Android app that can use “native” features as follows:

  • When the user adds, edits or deletes an item, a toast message will appear – use the Toast plugin
  • When a user ticks an item, their device vibrates – use Haptics plugin

With only 3 steps as on the homepage, we will work together.

1. Install CLI + core package and initialize

Terminal will then ask to enter the necessary information for initialization, such as the app name, the app’s package ID on the Play Store / App Store, and the directory after the build containing the index.html file for the Capacitor to recognize. In this example, I entered the following:

Capacitor todo app init

2. Install platform packages

Since I just want to create an Android app, I just need to run the following command to install it for Android:

To install for both platforms, you can add the package @capacitor/ios and then call npx cap add ios similarly.

3. Modify the code to use the “native” feature and build the app

As mentioned above, I will install 2 more plugins, Toast and Haptics, to integrate the “native” feature:

In src/tasks.js , I import the Toast plugin and call the Toast.show() function to display a message every time the user adds/update/remove an item.

In src/status.js , I import the Haptics plugin and call the Haptics.vibrate() function to vibrate the user’s device when they complete an item.

Then build source and sync with android folder with command:

3.x. Use Android Studio to package source code into app

At this step, you may wonder: why use Android Studio? Do you think Capacitor turns a web app into a mobile app without the need for a platform/OS specific IDE? The reason is because Capacitor doesn’t work like that. As mentioned above, Capacitor only acts as a bridge between your web codebase and the “native” environment of the operating system, simplifying the steps in the mobile app development process, however, packaging code and build into a mobile app must still be done by IDEs that are Android Studio (for Android) or Xcode (for iOS). But this step is not too complicated so you don’t have to worry.

To install Android Studio, you just go to the download page and then proceed with the normal installation. After installation, you can open Android Studio with your project with the command npx cap open android . Wait a moment for gradle to automatically install the necessary packages for the app. Finally, you can run the app directly on the simulator or your phone to experience, or build the source into an apk or bundle file to deploy to the store.

Android Studio run

In my case, after running the app on my phone, I enter a new item, a Toast shows the result like the code I edited:

Capacitor todo app success

So I have an Android app built from the web language, extremely easy and fast

Create a plugin yourself

In case your app is among the unlucky 1%, must use a certain “native” feature but no plugin is available, then Capacitor also supports all the steps so you can create one yourself. plugin for your app. The rest is not too difficult, just find a course to learn more about Java/Kotlin or Swift/Objective-C

Here I try to create a Capacitor plugin for Android (Android again, wish I could write a tutorial on iOS…). Assuming the use case is that my todo app wants to retrieve the device’s language information but no plugin has provided it yet, I will create a locale plugin by myself following these steps:

1. Initialize from plugin template

First, I used the generator that the Capacitor team developed to create a plugin framework:

Enter the necessary information for the generator plugin, once completed, you will have a project with a folder structure similar to the following:

Capacitor plugin structure

Here I will only be interested in 2 folders android and src :

  • android – Contains the source code of the plugin for Android (in android/src/main/java/com/.../LocalePlugin.java )
  • src – Contains the source code of the plugin for the web and a set of definitions in TS to bridge with Android or iOS source code.

2. Android side processing code

Accessing the long path to the source code of the Android plugin , you will see 2 files:

  • Locale.java – contains code that handles plugin logic
  • LocalePlugin.java – contains the code to communicate with the web

The above file organization helps to make my code logic clearer and easier to maintain if my plugin is relatively large, but since the plugin I plan to write is very small, I will only write the code in the LocalePlugin.java file. In this file, a short but complete sample code is available for the processing logic of an API plugin as follows:

I will edit this code to get the device’s locale information as follows:

Wow, nice logic…

3. Interface definition

In this step, I will define the getLocale function coded on the Android side in src/definitions.ts :

This interface will make it easy for you or someone else using this plugin to take advantage of intellisense’s type checking or code completion. Commenting on code is optional, but you probably already know the benefits of commenting code, let alone its importance when building APIs. Furthermore, the comments here act as documentation comments and will be generated along with the README file when you run the npm run docgen command that is already integrated with the plugin template.

4. Web-side processing code

In this step, I just need to create a corresponding getLocale function on the web side to connect to the Android side to be able to start using the plugin. In the src/web.ts file, you can also see a sample code available similar to Android. I modified it to return the browser’s language information as follows:

Note that if your app is targeting multiple platforms at the same time, either Web, Android or iOS, it’s necessary that you write code that handles multiple platforms, but if your app is only aimed For mobile platforms, in this file, you can implement empty functions without writing internal processing code.

Finally, just build the source with the command npm run build and then push it to npm to share with the community or import the package into your project to use. So I have a simple Capacitor plugin.

Conclude

Capacitor is indeed a powerful weapon for web developers, the simplicity, convenience and speed it brings is extremely valuable. If combined with specialized frameworks to develop cross-platform apps such as Ionic (with the same father), Framework7 , Quasar … it looks professional, no different from a real “native” app. consume. However, there is no such thing as a “silver bullet” technology that solves all problems. Each type of technology has its advantages and disadvantages in certain cases (requirements, scale, human resources, timeline, security, lead, PM, etc.). So it is necessary to ask questions, exchange and evaluate before deciding to choose.

Hope this post is helpful for you, thank you for following the article

Share the news now

Source : Viblo