Ionic Angular in a nutshell
Why I care about
I’ve developed several small websites in my spare time before. I’ve primarily used static site generators and JAMstack setups. However I’m still primarily a system and backend developer. I’ ve never planned to and I’ll never create such amazing interactive websites like the one shown below. You’ll see that Ionic is not suitable for such use cases anyway later.
Nevertheless in 2020 I had the pleasure to design a MVP for an industrial IoT application. Beeing a one (developer) man show at that time in an early stage startup one requirement was to support as much client device types as possible: Android devices, iPhones and web browsers in desktop machines. The MVP had to be developed as fast as possible of course. We requested some suggestions about practical exepriences from consulting companies.
After some further evaluation we ended up with Ionic Framework runnig Angular under the hood. At the time of writing I’m quite confident that we could not have chosen better. Let’s dive into cross-platform framework alernatives now.
tl;dr (too long, did not read)
I don’t want to waste your time. To be fair Ionic (at the time of writing: version 5) is not the best choice for every use case. Ionic 4 introduced a lot of major features which are still valid for Ionic 5 of course. The blog post Ionic 4: All you need to know summarizes when and when not to use Ionic 4 very well. The same applies to Ionic 5 as well.
When should you use it:
- Your main focus in Web then mobile.
- You are already using Angular.
- You want to migrate to a PWA but you still have users using your app and you want to provide a soft transition.
- You have low budget and you want to build a web site and mobile apps.
- Your app doesn’t need advanced UX, graphics or does not handle lots of data.
- You want to rely on open standards. You want to avoid updating your libraries every 2 months.
When shouldn’t you use it:
- Games or graphic intensive apps. → We do not need graphics and interaction intensive functionalities.
- Complex apps with lots of data and complicated state machine. Use React Native or Flutter for this. → ATM we are implementing state machines in Ionic Angular with Angular services and Angular components for page specific state machines and state machines for logic across several pages successfully. However one could use XState or an similar library with Angular as well.
- You want to build amazing user experiences and UI design is key for your business success. → For us beeing building IoT focussed applications the UI and UX capabilities of Ionic Angular are sufficient.
- You are already heavily using the React ecosystem and you want a great GraphQL integration using framework such as Vulcan or Gatsby. → We are using Ionic 5 Angular with GraphQL (with websocket based subscriptions) and it works perfectly fine!
Cross-platform framework alternatives
Before choosing Ionic you should have a look at alternative frameworks. In general one distinguishes between Native, Hybrid-Native and Hybrid-Web frameworks.
Apps created with native frameworks are written in operating system (version) specific code. If you want to support a broad range of operating systems this will imply that you have to create and maintain one app per each operating system you want to support. You can imagine… this might easily become a barrel without bottom and can potentially slow down adding business value to your product.
Apps created with hybrid-native frameworks are written in framework specific code but are running on several operating systems. However they do usually not support desktop apps. You’ll end up having to create one app for all mobile operating system (Android, iOS) plus one app per desktop operating system you want to support. W.r.t. effort a bit better than when choosing the native framework approach. However could still be un-manageable dependent on your team size.
Apps created with hybrid-web frameworks are written in framework specific code plus a backend technology and preferably open standards for communication between backend and frontend like RESTful APIs, GraphQL APIs, … . It’s possible to use ecosystem specific communication, frontend and frontend stacks like SignalR, Blazor and ASP.NET. However this tight coupling to non-standard technology can enforce the need for major future refactoring of the overall application! Which backend framework to choose has significant implications by the way. However the topic of choosing a suitable backend framework as well as backend/frontend integration communication for an Ionic Angular frontend based app is beyond the scope of this post. What’s relevant here… if it’s sufficient to provide the desktop version of the app you’ll end up creating one single app for all operating systems you want to support. In case a PWA for desktop operating systems is not sufficient you’ll have to potentially create one app per desktop operating system in addition. This means in case a PWA for desktop users is suitable using a hybrid-web framework significantly decreases development and maintenance effort.
- Android SDK (Android apps)
- iOS SDK (iOS apps, but can be run on macOS as well)
- macOS SDK (macOS apps)
- Windows 10 SDK (Windows 10 apps)
- different frameworks for apps running on several (e.g. Gnome, KDE, …) or specific (e.g. Elementary OS SDK, …) Linux distributions, refer e.g. to here
- React Native (Android and iOS apps with React)
- NativeScript (Android and iOS apps with Angular, React or Vue)
- Xamarin (Android and iOS apps with .NET and C#)
- Flutter (Android, iOS, desktop browser as well as native Windows, macOS and Linux apps)
- Ionic Framework (Android, iOS and desktop Electron/PWA apps with Angular, React or Vue)
Given our requirements and constraints the type of framework to choose was not a question. We wanted to use a hyrid-web frameowork.
Hybrid-web framework alternatives
W.r.t. backend/frontend integration technologies for Flutter there is everything one could potentially need: The http package for RESTful APIs, the graphql_flutter package for GraphQL APIs, mqtt_client for websocket based MQTT connections, etc. . For all potential Ionic Framework alternatives (Angular, React, Vue) there are equivalent packages for integration as well.
At the time of writing (2021) Flutter has already generated enormous momentum, especially w.r.t. support for native desktop apps for Windows, macOS and Linux. However in 2019 this was not foreseeable. I’m quite interested in how Flutter will evolve further into the desktop app area.
Ionic web framework choices
The next question to answer is what frontend framework to choose to be used in Ionic under the hood. Basically Ionic adds just another level of abstraction on top of a selection of frontend frameworks, integrations with these frameworks and an uniform design system provided by Ionic UI components.
- Ionic Angular is the integration of Ionic with the Angular framework.
- Ionic React is the integration of Ionic with the React framework.
- Ionic Vue is the integration of Ionic with the Vue framework.
In contrast to a native mobile Android or iPhone app Ionic uses WebView to render web apps in a full screen browser wrapped into a native app.
Again, I’ve read a ton of comparison blog posts like e.g. the one in the Vue docs and posts about experiences of people in practice with these frameworks. The post I Almost Got Fired for Choosing React in Our Enterprise App summarizes the impressions I developed over time about React as well as Vue quite nicely:
- “I just realized that React is not Java or .NET developer-friendly. Angular would have been a better choice in this case because of similar design patterns.”
- “So it is your and your team’s responsibility to develop an opinion about how to do it and especially what other libraries you want to use.”
- “Indeed, React is mostly backward-compatible, but the ecosystem around React is not. Developers and third-party libraries will always use the latest features and architecture patterns, while old experiments will be left behind to die.”
Of course in a startup you want to experiment. But you want to create skills with a framework which is long time maintainable and able to scale as well! We’ve decided taking the conservative, but stable path: Angular.
Sidenote: I evaluated a lot of Python Flask packages for microservices in the past and worked with Django as well. There are some similarities between Flask and React/Vue vs. Django and Angular w.r.t. commonly agreed on design patterns and time it take to get a small project done. With Flask you’ve to choose from third party packages to implement fundamental functionality. With Django one get’s a stable, maintained boilerplate at the expense of less flexibility out of the box. In retrospect choosing Angular is similar to choosing Django. Of course Django is not the best fit for Python based micro service based apps which have to scale. There is FastAPI which could significantly change the game in this area.
Ionic UI components
The building blocks of Ionic Angular you’ll discover first are the UI components. Ionic Angular provides many basic UI components like a menu, grid, card, buttons, tabs, etc. out of the box. The UI components use the native look and feel, e.g. on iPhone the corresponding design language of iOS and on Android as well as for Progressive Web App (PWA) viewed from a browser Material Design. UI components of the Ionic design system are built with Stencil which is maintained by the Ionic framework team. They are web components which has many benefits: “They work everywhere. They’re easy to customize. They help drive adoption. They’re future-proof. There are plenty of WC libraries to leverage.” They work on top of every framework and replace in case of Ionic Angular the design system of Angular.
Custom Ionic UI components
Custom UI components can be created like the builtin ones with Stencil. You may have a look at UI component libraries out there to get inspiration and a little guidance about the code structure. There are some tutorials available online like this (about how to create a button and modal) which help to get started with creating custom UI components.
The command line interface of Ionic is powerful, convenient and not overloaded. Some commands (e.g. for creating pages) add another level of abstraction on top of the Angular CLI. The cheatsheet shown below is of Ionic 2 but the one of Ionic 5 would be quite similar and helps to make the development workflow understandable.
Let’s have a look at the Ionic 5 Angular components an app consists of next.
Building blocks of Ionic framework based applications
As you’ve noticed in the workflow above project boilerplates can be generated from templates.
If you invoke the
ionic generate command line interface command you’ll get an interactive selection of the basic building blocks an Ionic Framework based app is built with.
There is no explanation of pages in the Ionic v5 documentation. However you get some info in the Ionic v3 documentation about pages. Pages are usually the different pages of the application which are routed to via navigation. Beeing a single page application a page is not a page in the technical sense but the content separation context only.
When we generate a component with
ionic generate page blub a bunch of files is generated into the
src/app/blub directory of the project.
blub.page.ts . In addition there is
src/app/blub/blub.page.scss which is an empty file and something is added to
src/app/app-routing.module.ts . Refer to here if you are interested in the file content.
A component in Ionic Angular is an Angular
Component “defines a class that contains application data and logic, and is associated with an HTML template that defines a view to be displayed in a target environment.”
When we generate a component with
ionic generate component blub a bunch of files is generated into the
src/app/blub directory of the project.
blub.component.ts as well as
blub.component.scss is which is an empty file. Refer to here if you are interested in the file content.
A service is an Angular Service which “is a broad category encompassing any value, function, or feature that an app needs. A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.”
It’s important to clarify the difference between a service and a component. Ideally a service contains any logic used by components. “Ideally, a component’s job is to enable the user experience and nothing more. A component should present properties and methods for data binding, in order to mediate between the view (…) and the application logic (…).”
We’ll have to fallback to the Ionic v3 docs again. An
IonicModule is a wrapper for an Angular
NgModule which is a “container(s) for a cohesive block of code dedicated to an application domain, a workflow, or a closely related set of capabilities.”
To be continued
I’ll continue with missing components, app navigation, app structuring, overall app state management, inter component communication, etc. soon. Stay tuned.