Most organizations with a web application will inevitably need to make a decision regarding their current front-end framework. I’ve personally been involved with two projects that have come to this crossroads. One of the two applications was written in AngularJS, the other in Backbone.js. In both cases, the organization decided that the best course of action was a full rewrite using React and Redux. In the case of the AngularJS app, a gradual migration approach was considered and I was lucky enough to have the opportunity to investigate this possibility.
On July 1, 2018, AngularJS will release version 1.7 and then enter a 3-year period of long term support. During this period, the team will address security concerns and maintain support for new versions of jQuery and web browsers, but there will be no significant improvements or advancements. Meanwhile, Angular (version 2+) and other frameworks like React will continue to be developed and improved. Depending on the complexity of your application and your staffing levels, it might make sense to keep using your existing framework during this time. But, for many organizations, ensuring their product avoids obsolescence is a significant enough reason to make a change.
The Gradual Approach
After choosing the framework, I began investigating what a gradual migration from AngularJS to React might look like. I started reading blog posts from other people who had attempted it and began investigating various tools to aid in the process. I started reading about libraries to convert React to AngularJS, AngularJS to React and some that simplify integrating Redux into Angular applications. Some of the libraries I found were no longer maintained, some had links to other libraries to which they had conceded defeat. Eventually, I determined that the two best solutions for my needs were react2angular (https://github.com/coatue-oss/react2angular) and ng-redux (https://github.com/angular-redux/ng-redux).
react2angular allows you to expose a React component to Angular as if it were an Angular component. What does this mean? I chose a fairly simple AngularJS directive from the existing code base and decided to replace it with a React component. The process was as follows:
- Create a React component
- Use the html from the AngularJS template to create the markup in the React component’s render method
- Rewrite the click handlers and basic functionality from the AngularJS controller in the React component
- Wrap the new react component in react2angular to expose it as an AngularJS component
It really wasn’t very difficult to do and it offered a great solution to what seemed on the surface to be a difficult problem.
ng-redux was the other library that I experimented with. The library is well documented and is a great solution for incorporating Redux into any AngularJS app independently of whether you intend to use React or not. You can easily connect AngularJS components to the Redux store similarly to the way you would a React component.
While the library was easy to use and configure, the real challenge here was in figuring out exactly how to migrate the state management of the application from AngularJS to Redux. I quickly realized that having a hybrid app relying the same information in two different states on the client was a nightmare. Ideally, I would suggest changing the entire state management layer of your application to Redux before introducing React. If this were not possible, I would change it over in “slices” by moving all of the state related to one object or model type at a time.
So, what’s the problem?
So, if both of these tools are so easy to use, why doesn’t everyone do this?
It can quickly make for a complicated code base. Depending on the experience level of your developers, exposing them to a hybrid of two frameworks could be very confusing. My biggest concern as I started down the path of “making this work” was that I found myself figuring out how to replace the existing AngularJS code with the equivalent in React. This was often not the same way I would architect a new React app. It’s hard to follow best practices for two very different front-end solutions at the same time. Ultimately you can end up with a confusing application full of hacky solutions that aren’t reflective of best practices in either framework.
When choosing to upgrade you have to choose the best approach for your organization. My conclusion was that whenever possible, the best course of action is to rebuild from scratch. The migration is possible, but it will probably take longer and you’ll inevitably make decisions regarding application architecture that facilitate the migration more than what’s best for your application. The argument for migrating gradually really comes down to staffing. If you have a small staff, there are a couple of scenarios where it may make sense to use this approach. If you need to keep pushing out new features in your existing codebase while making the migration, or if your application is so large, that you don’t feel like you could rewrite it in a reasonable amount of time, you may consider migrating gradually.