Migrating from Angular v1 to React

Published on den 18 September 2017

At Bokio we are currently moving from Angular 1 to React. We are about 2-3 weeks out from going to production with two of our four parts converted to React. This is how we went about it and what we learned so far. (This is also preparation for I talk about this I'm holding tomorrow so the format might be a bit strange)

Where we were

To understand why we made this move a short background is needed. In the beginning of 2015 Bokio as it is today was formed. Bokio has actually existed longer but then we merged two companies into one. Bokio was doing salaries and Efira was doing bookkeeping and invoicing. So it was a perfect match. BUT merging two codebases is not super easy. We took a shortcut and kept a lot of the original code. That allowed us to move very quickly we have been paying the price.

For the last 2,5 years we have been in average ~3 developers. Building a product for bookkeeping, invoices and salaries that have almost 25 000 companies signed up. After getting funded we are now growing rapidly from 4 developers a few weeks ago to around 20 people in the product team in 6 months.

But growing fast with little resources means shortcuts and we have a bunch of problems with our current front-end code:

  • Angular1 :(
  • Lots of JS errors (not showing for the user but clogg our logs)
  • 3 different applications with 3 different structures.
  • Mix of Typescript and JS (new code is written in TS but the old code prevent us from using a dev environment fully adapted for TS).
  • We have a failed native app project for expenses. We are better at web development.

Other problems are that:

  • Scanning receipts can't be done good enough in mobile web today.
  • We are onboarding ~15 new developers in a year. With the mess described above we would pay a big price for that.

Our goals

We had a few goals when we looked at how to solve our problems.

Onboarding developers must be easier

We had a few key areas we identified to make this easier.

  • Consistent structure. If we have one common code structure it's far less information to learn for a new developer to get started.
  • Typing. Yeah, I love typed languages. And there is a good reason for that. When you start on a new codebase it's so much easier if you actually know what properties there is you can use on an object.
  • Cleaner framework. Angular 1 is difficult. It's simply way too many concepts and different ways to do stuff. We always stayed away from most stuff because I believe that my developers should spend more time solving problems and less time reading documentation about how feature x works and then tie us harder into that framework.
  • Debugging experience. When you are new to a code base you probably rely more on the debugger to help you to quickly understand the code. Stepping through a few functions at least helps me to quickly get a good overview. Angular wasn't very friendly for this.

Better quality

  • Less errors. Even if the error isn't showing to the user having them show up in our logs hide the important problems.
  • Better stack traces. Angular 1 stack traces are just shy of being hostile. I almost doubt they could be made worse even if someone actually tried to.
  • Typing from server to HTML. At Bokio we generate a typescript proxy for our APIs. But with Angular 1 we could only get typing in the controller. Not down to the HTML which led to errors like some value going missing because we changed the casing and missed to update the .html file.

Developer happiness and productivity

I truly belive that if you want people to do great work you need to make it enjoyable for them to do so. Here are some things we wanted to improve.

  • No context switch between view and controller. Less swapping between files.
  • Less framework things/crap to learn.
  • Better tooling.
  • Typed language files. Figuring out which language keys we have to use would be so much faster and easier.
  • Tslint!
  • Understandable and traceable re-renders. Ever tried to figure out why Angular is re-rendering? Good luck.
  • Local styles. Handling styling on a team scale is quite annoying otherwise.

Preferebly be able to reuse as much code as possible for app-development

And it's not just the code we want to reuse. We also want to be able to reuse our knowledge and process.

So React it is, what now?

Looking att all our requirements React with typescript felt like the best match. One big consideration was that everybody using it seemed very happy with React.

Plan and take-aways

Migrating parts of the application

Because our application was already divided into different parts it wasn't really a far stretch to simply migrate the parts one by one. If you have that it's a luxury. Because for us that has meant that we can reduce the scope of the migration untill release and get new code out faster. Not doing all the parts at the same time allow us to learn our lesson in the process. We just need to make sure to take the time to update the already migrated parts when we learn new approaches.

Prototype

We decided to start with a prototype. From the beginning we planned to do a throw away prototype but we actually built the prototype a bit too large for that and decided to keep working on that one instead. We have been pretty rough with that code and thrown out quite a bit though. After we release the current parts we will spend a few days on cleaning up even more before moving on to our last two parts.

Take-away: Don't build too much into the prototype. Make small increments and evaluate early how it feels. We also had one single person working on this. That was a misstake as it would have been more valuable to have proper team discussions. Prototyping with the new framework is quite essentials if you want to make a good choice.

Keeping it simple

Doing a full rewrite is expensive. It takes time and effort. Don't put too much strain on the developers right away. Learning a new framework is enough. Learning a bunch of other things at the same time makes it very overwhelming and it also makes it harder to evaluate how well the new framework lives up to your expectations.

In our case we started by thinking that we should use redux because the theory is awesome. It turns out redux comes with a lot of overhead and without having used React with this.setState it's very hard to get a good feeling for why you are paying the complexity tax that redux brings. The biggest problem is actually that designing the global state takes a lot of thinking and effort if you want to get it right.

After a while we realised that it was better for us to start with the basics. Which meant we want back to direct querying in the components. Very much like our angular code was written. Doing this has allowed us to port things far more easy and because the code is more similar it's easier to avoid any regressions.

Take-away: Small steps! Try to do the migration as close to the original as possible and then you can start thinking about improving stuff. Another approach here is to spend far more time prototyping our be able to test with a few smaller projects first.

Mobile web before app

Remember that one of our goals was to build a mobile app? Our decision is to let the web come first. There is a few reasons for that.

  • The web reaches more people
  • We have more web experience
  • Debugging errors is far easier in the web
  • Deploying new versions takes minutes, not weeks

The result

So quite far into the process the team is very happy. There are a few things that was easier to do in Angular but most of the time everybody prefers React. The feedback is that React is far easier to learn because there are less concepts. The Css also becomes easier thanks to local styles.

It also feels that the developers learn more programming using React. When using Angular they spent much time learning how to do Angular. Now they are instead learning how to code.

We could probably get better performance by doing redux and global state. But honestly, we don't have a problem with that today because our server side code is fast and can handle some extra queries for now. I'm very happy that we decided to not add the complexity of redux and designing the global state. I think we will go there later, but it's better if the team learns the reasons for going there first.

Then feel free to it or if you have any comments or questions mention @MikaelEliasson on Twitter.

CTO and co-founder at Bokio with a background as an elite athlete. Still doing a lot of sports but more for fun.

#development, #web, #orienteering, #running, #cycling, #boardgames, #personaldevelopment