Tutorial hero
Lesson icon

Building a PWA with Stencil: An Introduction to StencilJS

Originally published January 24, 2018 Time 11 mins

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

The end result of this article series is going to be Progressive Web Application built with the StencilJS 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. The reason for this is that this series was originally written around the time when Ionic/Angular was the only way to build Ionic applications. 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? Preference, mostly.
  • Does this mean that I shouldn’t build a PWA with Ionic/Angular anymore? 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 now to give you an overview:

Stencil & Ionic Ecosystem Chart

StencilJS helps us create web components, and the Ionic team have created a bunch of web components with Stencil which have 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 constitutes 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) and can help with integration specifically with Angular. The Ionic team are also building out specific integrations for React with @ionic/react and Vue with @ionic/vue. These framework specific packages are useful, but they are not required in order to use Ionic.

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 and have no interest in changing your tech stack - don’t worry. There have been updates to accommodate this ecosystem change in @ionic/angular, but the way you build applications with Ionic/Angular has remained mostly the same. 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 package is created.

What is StencilJS?

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:

StencilJS 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 element does not exist in standard HTML, but we can define a “custom element” 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, h } from '@stencil/core';

@Component({
  tag: 'my-first-component',
  styleUrl: 'my-first-component.css',
})
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 for passing data into and out of components, we use @Prop and @Event. Instead of double curly braces {{name}} for interpolations we use single curly braces {this.name} to render out data in our template. Instead of creating a template inline or in a separate file, we define it inside of a render() function that returns the template using JSX.

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, Vue, 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 often come with a performance cost.

You then might consider the question as being a situation 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 might make a difference.

An important thing to keep in mind that is that just because you are using StencilJS it doesn’t mean your application will perform well. Until your code is highly optimised and designed as well as it can be, the much bigger factor in performance is going to be how you have built the application. If you are interested, I have written more on what you should be keeping in mind for performance here: Ionic Framework Is Fast (But Your Code Might Not Be).

For most people, I think these are the key factors to consider when deciding between Ionic/Angular and StencilJS are:

Use Stencil:

  • If you are already quite comfortable with modern JavaScript and web development concepts
  • You like the idea of not needing to include a traditional framework and you want to keep your application sizes optimised/small
  • You prefer using standard JavaScript over using framework specific concepts & syntax

Use Angular:

  • You already use and are happy with Angular
  • If you are not as comfortable with modern JavaScript and web development concepts, and will need to rely more heavily on community resources and tutorials
  • You like the idea of conforming to a well-defined application architecture rather than deciding on implementation details yourself
  • You would like more development convenience features built-in rather than keeping application sizes as optimised/small as possible

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. If you would like more help deciding between Angular and StencilJS, you can take a look at: StencilJS vs Angular for Building Ionic Applications.

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.

Part 1: An Introduction to Stencil (this tutorial)
Part 2: Project Structure and Syntax
Part 3: Rendering Layouts
Part 4: Routing and Forms
Part 5: Storage and Services
Learn to build modern Angular apps with my course