Since Ionic now uses web components to deliver their collection of user interface elements for building mobile applications, we are not limited to building Ionic applications in just one way. Web components can work with any JavaScript framework, or without even using a framework at all. This degree of freedom is fantastic, but perhaps also a little confusing. If you are a beginner, just getting started with Ionic, you might not have any idea what approach you want to use - or perhaps even why you (probably) need to use something like StencilJS or Angular with Ionic. Now you have a complicated decision to make before you can even get started.
As someone who teaches both StencilJS and Angular for building Ionic applications, I have been trying to figure out how best to answer the question:
“Should I use Stencil or Angular to build Ionic applications?”
Especially since I now have books targeted at beginner to intermediate Ionic developers for both of these options, I wanted to be able to provide some guidance on how you might go about deciding. It feels like a big decision to make when you are just getting started - you don’t want to make the “wrong” choice. If you find yourself in this position now, hopefully, I can put you at ease a little bit by offering my point of view that I don’t think there is a wrong choice to make here, there are just different choices.
The conclusion to these kinds of articles are almost always “it depends” - this is usually for good reason, and this one will be no different. It is also worth keeping in mind that StencilJS and Angular are not the only two options for building Ionic applications, these are just the options that I prefer and that I have experience with. Although I won’t be talking about the specifics of approaches like React and Vue for building Ionic applications, a lot of the points I will make about Angular will also apply to React and Vue to some degree.
Although we typically use a framework in combination with Ionic’s web components (Ionic mostly handles the user interface, whereas the framework deals with a lot of the application logic), StencilJS can fill the role of a framework for us but it is actually a web component compiler, not a framework. In this sense, Angular/React/Vue are similar as they are more like traditional frameworks, whereas StencilJS takes quite a different approach. This is why some of the comparisons I make between StencilJS and Angular can also be applied to React and Vue.
I can’t give you a definitive answer in this article, but I did want to provide a “too long, didn’t read” summary at the beginning which boils down the key points I will make and expand upon throughout the article. This is a simplistic overview, but if you don’t feel like you have any other basis for making a decision between the two approaches, these points should help.
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:
- 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
If you’re really stuck, just pick either and decide later if you want to switch. They are both fantastic approaches, and it isn’t that important of a decision - you can always come back and attempt the other approach if you feel like one way isn’t clicking with you. You might see picking the “wrong” approach for you initially as a waste of time, but I really don’t think that it is. Learning something in two different contexts can really help to reinforce concepts, and having a bit more knowledge about a popular technology (even if you don’t end up using it) can be helpful.
In the rest of this article, I am going to expand on some of the aspects I considered when coming to my recommendations.
General Philosophy/Methodology
If you were to look at the project structure of an Ionic/StencilJS and an Ionic/Angular project, you would see that they are actually very similar.
They both have a src folder where most of your coding happens and a www folder that contains the built output of your application. Most of your application will be built, in both cases, by building out a bunch of different components - these components are nested within one another and displayed using (usually) a URL based routing/navigation system. They even both have an assets folder for serving your static assets like images and they also have global files for storing global CSS rules.
If you were to switch from StencilJS to Angular or vice versa, you would likely already feel very at home within the general structure of the project. Where the main differences come in is in the building of the various components and services your application will use, and the general methodology of the approaches.
The key difference between the two is that StencilJS is a web component compiler, whereas Angular is a more typical application framework. StencilJS relies primarily on the power of browsers and the web component specification, whereas Angular ships code with your application to power the framework.
StencilJS does have a few specific concepts you will need to learn, but for the most part, you are just building with standard modern JavaScript/TypeScript. StencilJS gives you the key features/structure you need to effectively build an application, but relies on standard browser implementations for most of the functionality.
Angular has a lot of Angular specific concepts to learn, but although it is less so than with StencilJS, a large chunk of your coding will still use standard JavaScript/TypeScript. Angular has a lot more functionality built-in to the framework itself, and you will find that there are “Angular ways” to do things out of the box like HTTP requests, form management, DOM manipulation, and more.
To give you a quick overview, let’s take a look at a couple of specific examples
In Angular, we would use the Angular specific concepts/syntax for creating our templates. One common scenario in a template is to loop over data and display part of a template associated with that data. For example, we might want to loop over every element in a “todos” array, and we want to render out each todo to the template. Assume in this example that for both cases we have a “todos” class member that contains an array of all of our todos available on “this.todos”.
With Angular, we would achieve that using Angular’s special *ngFor
structural directive, which would look like this:
<ion-list>
<ion-item *ngFor="let todo of todos">
<ion-label>{{todo.title}}</ion-label>
</ion-item>
</ion-list>
In StencilJS, we would just use standard JavaScript concepts to loop over our data. To achieve this same functionality, we would use the standard map
operator on our array, which allows us to loop through each element in the array, and we can return a part of the template for each element:
<ion-list>
{this.todos.map((todo) => (
<ion-item>
<ion-label>{todo.title}</ion-label>
</ion-item>
))}
</ion-list>
NOTE: StencilJS also uses JSX for templates, which allows you to use JavaScript and HTML together.
If we wanted to create some kind of singleton service to share data or functionality throughout an application, we can achieve this quite easily with either Angular or StencilJS, but in somewhat different ways.
Again, Angular has some specific built-in concepts for this. In the case of a singleton service, we would create the service using an @Injectable
and then we would “inject” it into classes that we wanted to make use of the service in using Angular’s concept of dependency injection through the constructor
:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class TodoService {
public todos = [];
addTodo(todo){
this.todos.push(todo);
}
}
import { Component } from '@angular/core';
import { TodoService } from '../services/todo.service';
@Component({
selector: 'app-home',
templateUrl: './home.page.html',
styleUrls: ['./home.page.scss']
})
export class HomePage {
constructor(public todoService: TodoService){
}
myMethod(){
this.todoService.addTodo({
title: 'test'
});
}
}
This sets up our service on a todoService
class member, and will allow us to use it throughout the class with this.todoService
.
When using StencilJS there is no pre-defined way in which you should go about this. Instead, you can just fall back to standard JavaScript concepts. One way we could implement this in StencilJS, and it is the method that I typically use, is to create and export the class that implements the service, and then just use standard imports to make that functionality available elsewhere in the application:
class TodoServiceController {
public todos = [];
addTodo(todo){
this.todos.push(todo);
}
}
export const TodoService = new TodoServiceController();
import { Component, State, h } from '@stencil/core';
import { TodoService } from '../../services/todos';
@Component({
tag: 'app-home',
styleUrl: 'app-home.css',
})
export class AppHome {
myMethod() {
TodoService.addTodo({
title: 'test',
});
}
}
In my opinion, the StencilJS approach here is a bit easier. But perhaps the downside is that since there is no particular “StencilJS way” that you have to use, it might be harder to figure out what you should be doing initially (this is a problem I aimed to alleviate with my StencilJS book, by providing examples of ways to handle most common scenarios).
Difficulty/Learning Curve
It’s difficult to say whether StencilJS or Angular would be easier for a beginner to learn (especially since I originally learned Angular years before StencilJS existed), but on the whole, I would hazard a guess and say: StencilJS is the easier option.
StencilJS is mostly a bit of extra tooling around standard JavaScript, whereas Angular is a full-blown framework. Naturally, there is a lot more to learn before you can become efficient with Angular. There are quite a few concepts in Angular that can be tricky to wrap your head around initially.
With that said, although it might take a longer time to learn the various Angular concepts, there are also some benefits to this. I’ve touched on this a bit in this article, but Angular is quite “opinionated” and there is generally always an “Angular way” to do things. In a way, this can be helpful to beginners even if it does create some friction. In a sense, you are given less freedom, but as a beginner who might not really know how to approach a lot of situations, this can be a good thing.
Community and Resources
The community and resources available around a particular technology are hugely important, especially for beginners. StencilJS is far younger than Angular, so naturally, there are far more resources and tutorials available for Angular.
If you feel like you are going to need heavy guidance for building features in your application, and would benefit a great deal from following guided tutorials, then this is a big factor to consider. The web is full of Angular tutorials as it has been around for many years.
This doesn’t mean there isn’t also a lot of support for StencilJS, and there is an interesting factor to consider here. The StencilJS community and StencilJS specific resources will continue to grow over time, but remember that we aren’t really building “StencilJS Apps” we are just building JavaScript apps with Stencil. This means that you can apply any generic JavaScript/Web Development advice/tutorials to building your StencilJS applications. The downside is that the advice/tutorials may be a bit more difficult to apply as they often won’t be written specifically in the context of a StencilJS application.
Summary
I’ve tried to keep this article as factual, fair, and to the point as I can. I don’t really have much of a natural bias here anyway since I actively use both of these approaches, and I sell products that teach both of these approaches.
Nonetheless, it is quite difficult to create a fair comparison between any two similar technologies, and impossible to capture all the nuances when trying to simplify things. There are many factors and considerations that aren’t talked about in this article, but I feel that this should serve as a reasonable summary for somebody trying to decide between the two.
If you have the time, I’d recommend not relying on my summary and to just give both a try. See what clicks more with you and what you find fun, because I think that is one of the biggest factors.