Angular: Batteries Not Needed
One of the primary reasons we chose Angular when we started YoPrint is that it includes batteries. Just use the CLI to generate a new app, and boom! You have everything you need. You don’t need to install any more libraries. We feared that if we chose something like React, we would need to put our stack together, and we might put it together wrongly.
It turns out that fear was unwarranted. Thanks to the robust ecosystem, it was pretty trivial to put it together, and YoPrint didn’t need anything too special.
Furthermore, we use Nx mono repo, so bootstrapping a React app was trivial.
The React Stack
We only needed to make four choices:
A Router
We chose React Router Dom
An HTTP Client
We chose Axios. We could have used native fetch, but we needed interceptors.
A UI Library
We chose MUI. The quality of this library has been a welcome surprise.
State Management Library
We chose Redux Toolkit + Redux.js. This is where you will need to consider the scope and needs of your app and choose something that works for you. You can also choose not to start with one. React has pretty good state management on its own.
We picked the popular choices then, which has served us great so far. It’s been over a year since we rewrote our Customer Portal App in React, and we have been happy with our choice. We are rewriting our Admin Portal App, which is far more complex.
MUI > Angular Material
I will say that MUI is a better and more flexible implementation of Angular Material. For the longest time, Angular Material didn’t even have a date range selector, and even when they added it after so many years of waiting, they didn’t have multiple months view. MUI had it, and it was beautiful.
Furthermore, we needed the UI to be dense, but in Angular Material, you must update the CSS to make it happen. In MUI, you add size=” small” and are done. It looks Angular Material 15 finally made it easier.
MUI came with many more components and customizability out of the box and was much easier to use. I wish the Angular Material team could take notes here.
RTK > NgRX
We love Thunks! It’s a simple and elegant solution. For example, when the user clicks on “+ Sales Order,” we can dispatch a thunk to create the sales order, wait for the promise to resolve, get the Order Id, and navigate the user to the page. All in one fell swoop.
To do this with NgRX:
- Create 3 Actions: Sales Order Create, Sales Order Create Fulfilled, Sales Order Create Rejected.
- Add an Effect that listens for Sales Order Create, makes the API call, and dispatches the corresponding action.
- Add another Effect to listen for Sales Order Create Success and navigate the user to the page. Alternatively, you can inject the Actions in the component and listen for all actions dispatched. YoPrint doesn’t need anything special, and Thunks works fine for us. The code ends up being simple, easy to read, and easy to reason about.
Batteries Holding You Hostage?
Everything is fine until it isn’t. When we tried moving away from Angular, we realized the batteries were a prison.
The very first thing we had to do when rewriting our code in React was rewrite all of our Angular HTTP Client to be in Axios. Axios works fine in Angular and React, but Angular HTTP Client was constrained to Angular. We’ve since abstracted all the HTTP calls into a library. If in the future, we decide to move away from React, we no longer have to rewrite the HTTP calls.
The same with NgRX. NgRX doesn’t work outside of Angular, and we had to rewrite it with RTK and Redux.js. It works great with both Angular and React, and we no longer have to rewrite that part of the code if we want to move away from React.
Separating each layer into a library makes reusing the code across our different apps easy. We wired up a React Native and Electron App using the same state management library with minimal effort.
Closing Thoughts
If you choose Angular because you are afraid to assemble your stack, you are making a mistake. Unlike backend engineering, you only need a router, an HTTP client, state management (optional), and a UI library. If you are unsure, go with the popular choices. Unless your app needs something special, if it’s good enough for the majority, it’s good enough for you.