This article is part of the Ionic Framework / Capacitor Advent Calendar 2020. It's the final day—finally!!
When evaluating a product or OSS project, scoping things properly matters. In practice, though, conversations often drift off scope—something like "use Ionic to get the app ready for the app store"—and while smooth communication is fine, that example really covers two different things:
- Reviewing UI components against mobile design guidelines (Material Design, and so on)
- Making the app store-ready in a technical sense by building natively with Cordova/Capacitor
To prevent that kind of miscommunication, let's properly organize Ionic and the ecosystem around it.
Ionic and Its Surrounding Ecosystem
Ionic Framework
@ionic/core
A UI component framework focused on mobile UI. It is built with Web Components, a web standard. Ionic/Core is largely made up of three parts.
DOM Components
Components expressed as Web Components in HTML. They make up most of Ionic Framework. For example:
<ion-button>Default</ion-button>
API Components
Components built and invoked in JavaScript as Web Components. You write something like the following, but under the hood it is createElement and dynamically constructing Web Components.
async function presentActionSheet() {
const actionSheet = document.createElement('ion-action-sheet');
actionSheet.header = 'Albums';
actionSheet.buttons = [{
text: 'Delete',
handler: () => {
console.log('Delete clicked');
}
}, {
text: 'Cancel',
}];
document.body.appendChild(actionSheet);
return actionSheet.present();
}
Global CSS / CSS Utilities
One of the main features of Web Components is Shadow DOM, which scopes CSS styles inside the DOM. Separately from that, Ionic/Core also provides global CSS and CSS helpers usable globally. Use them like this:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css"/>
<div class="ion-text-center ion-padding"></div>
@ionic/(JavaScript Framework)
So far @ionic/angular, @ionic/react, and @ionic/vue have been released. Because @ionic/core is Web Components, you can load it directly from any JavaScript framework, but two problems come up:
- Type support
- Routing
Types can be worked around somehow, but routing follows each JavaScript framework's conventions—changing state on the URL while stacking views—and parts inevitably diverge from @ionic/core. That is why @ionic/angular, @ionic/react, and @ionic/vue exist: they optimize @ionic/core for each framework and deliver mobile UI through the framework router.
stencil
A library the Ionic team develops for building Web Components with JSX. You write something like this:
import { Component, Prop, h } from '@stencil/core';
@Component({
tag: 'my-embedded-component'
})
export class MyEmbeddedComponent {
@Prop() color: string = 'blue';
render() {
return (
<div>My favorite color is {this.color}</div>
);
}
}
It was created to develop Ionic Framework and development continues today. It also has documentation auto-generation—or rather, stencil ships with routing and SSG, so you can build websites and apps with it alone—but at its core it is a library for developing Web Components.
Capacitor
A cross-platform development library from the Ionic team. It takes web assets as the source and can build iOS/Android WebView apps. If you are curious how the WebView is invoked from native code, see the following article.
https://note.com/rdlabo/n/n49c9694fd9d6
To use native features, you can use Capacitor plugins from official/OSS sources, and with some exceptions Cordova plugins as well.
Capacitor elements
A shared component library planned for full introduction in Capacitor 3 that switches automatically by platform. For the camera, for example:
- On the web, camera functionality implemented as Web Components
- On iOS/Android, calling the camera from native APIs
- All accessible through the same interface
Ionic is primarily Web Components, while Capacitor elements aims to provide the same UI and implementation cross-platform, including the web.
Cordova
A cross-platform development library from the Apache Foundation. It serves a similar purpose to Capacitor, but whereas Capacitor lets you manage native code, Cordova regenerates it on every build.
That means you do not need native knowledge—a plus—but when "the build suddenly errors for no clear reason," it is hard to fix. Capacitor plugins cannot be used, by the way.
Ionic Native
Because Cordova has history (2009 onward), many Cordova plugins are implemented with callback functions and are not TypeScript, which can be inconvenient for modern development.
Ionic Native is a Cordova plugin wrapper the Ionic team develops to address those issues. Install a Cordova plugin and the matching Ionic Native package, and you can operate the Cordova plugin through Ionic Native.
Closing
Once you organize the scope, you notice things like:
- Can Ionic be used together with library X? → Yes—just Web Components with no dependency
- Ionic Native is buggy! → It is only a wrapper, so look at the Cordova plugin's own issues, not Ionic Native
- Is Ionic supported with Riot? → You can use Web Components, but splitting duties with Riot Router looks tough
2020 is ending, so I hope organizing this knowledge helps you welcome 2021.
See you again.