PWA Toolkit Logo

Building a PWA with Stencil: An Introduction to Stencil



·

Part 1: An Introduction to Stencil (this tutorial)
Part 2: Project Structure and Syntax
Part 3: Rendering Layouts
Part 4: Routing and Forms

The end result of this article series is going to be Progressive Web Application built with the Stencil web component compiler. However, I think we need to talk about a few things before we get there. Given a lot of the recent developments, I want to tread carefully in explaining everything, because it will be very easy to become lost in A Sea of Frameworks and Acronyms (surely, George R. R. Martin’s next bestseller).

This tutorial series is targeted at people who are already familiar with building Ionic/Angular applications – many concepts will be explained in that context. You will still be able to progress through this tutorial series if you are not already familiar with Ionic/Angular, but you may find that some sections are light on details if the concept is something that Ionic or Angular developers would already be familiar with.

For those of you who have been building Ionic/Angular applications, and especially those of you who recently read my series on building a PWA using Ionic/Angular, it may be hard to get a handle on the new ecosystem that we find ourselves in. Some questions that might be popping into your head now might include:

  • I thought Stencil was a behind the scenes tool for Ionic 4? It is.
  • Are we going to need to learn Stencil to use Ionic now? No.
  • Do we need to learn Stencil to build PWAs with Ionic? No.
  • Should I learn Stencil? Maybe.
  • Why would I build a PWA with Stencil when I can build one with Ionic/Angular? Performance, mostly.
  • Does that mean that I shouldn’t build a PWA with Ionic/Angular? No.
  • Is Ionic/Angular being deprecated? No.

I hope to address most of these questions in detail, without adding to the confusion, in this article. As a start, here is a simplistic diagram of the ecosystem as I see it to give you an overview:

Stencil & Ionic Ecosystem Chart

Stencil creates web components, and the Ionic team has created a bunch of web components with Stencil which has become Ionic Core. Stencil can also be used to create web components for any purpose, it is not only used to create Ionic components. The bundle of web components that is Ionic can then be used by any framework, and it can also be used without a framework at all. There is a special library called ionic-angular which is the Ionic library framework that is specific to Angular (the one we have been using for a long time). This provides extra functionality that can only be used in Angular (like push/pop navigation), but it will still use the same Ionic web components under the hood.

If that doesn’t make sense, the rest of this article should help clear things up. But let me clear one thing up first: If you have happily been building Ionic/Angular applications since the release of Ionic 2 – don’t worry. There will be an update to accommodate this ecosystem change in ionic-angular, but there will be very little you need to change in your existing applications. You can, more or less, just continue building your Ionic applications as you have been and ignore everything I’m talking about here.

The diagram above highlights this fact. If you are building Ionic applications right now, then you are all the way at the bottom of that chart using Angular, and the ionic-angular package that is supplied to it. It doesn’t need to concern you how that ionic-angular library is created.

What is Stencil?

Hopefully, the introduction section will have given you a decent overview of how Stencil fits into the Ionic ecosystem. Now let’s take a couple of steps back and talk a little more specifically about what StencilJS is all about. To put it simply:

Stencil is a web component compiler.

A web component is basically a custom HTML element that we can define, and we can attach some behaviour to that element. We might create a web component called <my-avatar> that we want to use in templates to easily format profile pictures. This tag does not exist in HTML, but we can define it using a web component. Stencil can help us create these web components.

In Stencil, we can create web components using the following syntax:

import { Component, Prop } from '@stencil/core';

@Component({
  tag: 'my-first-component',
  styleUrl: 'my-first-component.scss'
})
export class MyComponent {

  // Indicate that name should be a public property on the component
  @Prop() name: string;

  render() {
    return (
      <p>
        My name is {this.name}
      </p>
    );
  }
}

This would create a web component that we can use that will look like this: <my-first-component name="Josh"></my-first-component>.

We will be talking through the syntax a lot more in the next tutorial in this series, but a lot of it is analogous to Angular. Instead of @Input and @Output we use @Prop and @Event. Instead of double curly braces {{name}} we use single curly braces {this.name}. Instead of creating a template inline or in a separate file, we define it inside of a render() function.

If you have an Ionic/Angular background, “components” are not exactly a new concept – the entire Angular framework is based on creating components like this. We generally either use the custom components that Ionic provides for us, or we can also define our own custom components in Angular. The difference is that in Angular, it is the Angular framework powering these custom components. With the web components that Stencil creates, it just works in the browser by default without having to use a framework.

You might respond to that with… well, it still does require a framework because it uses Stencil. It is more useful to think of Stencil as a compiler rather than a framework like Angular, VueJS, or React. Although we write the web components using Stencil, and Stencil syntax, Stencil will compile that code into plain JavaScript in the end. The code that ends up running in the browser is not Stencil code, it is just plain JavaScript/Web Components.

Why use Stencil to Build a PWA instead of Ionic/Angular?

We can use Stencil to build web components that can just run by themselves. We could create an entire project using Stencil and have it compiled into web components that will run directly in the browser – no need to include any frameworks. In fact, that is what we will be doing in this series to create a PWA. We will be mixing in Ionic web components (that the Ionic team created with Stencil) with our own web components (that we will create using Stencil).

However, we can also use those same Ionic web components inside of a “normal” Ionic/Angular application like we did in this tutorial to create a PWA. In this case, we would use the ionic-angular package, and our application will use the web components the Ionic team created with Stencil behind the scenes, but we would create the rest of our application using Angular components. In this scenario, you don’t need to know a thing about Stencil.

Naturally, the question arises… why would you use one over the other?

The Ionic team has spent a lot of time optimising for performance (especially on low-end devices), a process which includes making everything as small as possible. If a framework is being included, you are going to hit a wall eventually. The framework needs to be included in the bundle and loaded. Using a framework also means that it is going to be doing the things required to make that framework work (like change detection, for example) – these convenience features inevitably come at a performance cost.

The question then is one of cost vs. reward. Do you want to make performance the priority whilst sacrificing certain features, or are you happy to take a small performance hit and gain the advantages the framework provides? Angular, and other frameworks, are by no means slow (Angular has been designed with mobile usage as a priority). When your applications are designed well, they can work exceptionally fast. But when you’re getting into optimising for milliseconds, and prioritising low-end devices and networks, the weight of the framework can make a difference.

Except for in special circumstances, my advice for choosing between technologies is to pick the one you like or the one that will allow you or your team to achieve your goals easier. Performance is an important metric, but there are many other factors to consider.

This is the exciting thing about the approach the Ionic team is taking. Since everything they are doing is no longer framework specific, you can do whatever the heck you like.

Summary

The goal of this first article is just to get your feet wet a little, and hopefully help explain the difference between Ionic, Stencil, ionic-angular, and so on.

In the next article in this series, we will start taking a look at how to use Stencil and explain the syntax in more depth. We will also be taking a look at the Ionic PWA Toolkit which we will be using to help build our own Stencil/Ionic PWA.

What to watch next...