From a Brown Field to One in Bloom: Revitalizing AngularJS with React

From a Brown Field to One in Bloom: Revitalizing AngularJS with React

PUBBLICATO IL 06/05/2025 DA

Gianluca La Manna

Frontend Developer

If you have worked at least once on a brownfield project, you know how difficult and frustrating it can be.

You can use old approaches, but you're probably writing code without the Typescript superset. Furthermore, you are losing all the functionalities that a new framework has, which compromises the velocity and the devEx.

We can write the entire solution with another framework. Probably, this won't be a good idea, basically for two reasons:

  • Time ⏰
  • Costs 💸

The good news is that you can write the new features with the latest framework while keeping the old features. If you have good craftsmanship, you will be able to use the strangler fig pattern by Martin Fowler, promoting a smooth and clean transition.

From brownfield to one in bloom 🌸, but how?

AngularJS issues

We take the example of AngularJS.

The most significant risk of staying on AngularJS is safety, given that Google doesn't provide new security patches.

Another big issue is the two-way-data-binding. Each change in UI is reflected in the model and vice versa.

Each state change synchronizes more variables, and the use of a digest cycle can slow the application.

The next example of how AngularJS makes you suffer is Dependency Injection 💉. In AngularJS, dependencies are injected by the name of an argument.

    
        function MyController($scope, $state) {
        // …
        }
    

Here, the .toString() method is called, which extracts the argument names and then compares them with the already registered dependencies.

So, when you minify the code, it stops working.

Ultimately, we won't have TypeScript and all its advantages.

Perhaps we have enough points to think about writing with a new framework:

  • Safety
  • Two way data binding
  • DI
  • TS

Now, let's see how to integrate React into the AngularJS application.

Scaffolding React

The idea is to create a new folder in the AngularJS project's tree structure called app-new . This will be the entry point of our React application. Here, we can install the latest version of React. Preferably, we will install React with the Vite plugin.

Then, we will have a similar tree:

    
        /
        β”œβ”€β”€ app
        β”‚ β”œβ”€β”€ assets
        β”‚ β”œβ”€β”€ modules
        β”‚ └── package.json
        β”œβ”€β”€ app-new
        β”‚ └── public
        β”‚ β”œβ”€β”€ src
        β”‚ └── package.json
        β”œβ”€β”€ assets
        β”œβ”€β”€ cypress
        └── doc
    

As you can see, we have two package.json. One for app (AngularJS) and one for app-new (React)

Integration layer between two apps

We will create an Angular component that we will call into the routes.js file. Then, we will define a new route for this component.

    
    .state('react-home', {
        url: '/home',
        template: '',
        data: { requiresAuth: true }
    })
    

Here, we can pass any props for this component.

Then, in the index.js Angular file, we should define a scope variable.

This variable defines a base URL that will be used from React.

      
    scope.NEW_APP_BASE_URL = 'http://localhost:3000';
    

The controller, instead, should be something like that:

    
    (function () {
        const controller = function ($sce) {
            const ctrl = this;
            ctrl.$onInit = () => {
            ctrl.baseUrl = window.NEW_APP_BASE_URL;
            ctrl.url =$sce.trustAsResourceUrl(`${ctrl.baseUrl}/app-new/`);
            };
        };
        angular.module('libClient.common').component('appNewWrapper', {
            bindings: {},
            templateUrl:'/modules/common/component/appNewWrapper/appNewWrapper.html',
            controller: ['$sce', controller]
        });
    })();
    

and the view

    
    <iframe name="iframe1" frameBorder="0" width="100%" height="100%" scrolling="no" 
    src="{{$ctrl.url}}" allow="camera; microphone; display-capture;geolocation"></iframe>
    

Here's a little summary:

react

Generally, the iframe is not a good idea for several reasons. The basic idea is to use it only for the transition from Angular to React, then remove it. With iframe, if you have SEO on your website, you may be penalized by Google indexing and have a ranking problem, in addition to various security issues.

So, we will have 2 apps launched on different ports.

To call our React components inside the iframe, let's define them in our AppRouter with the correct url that will open the iframe

    
    const AppRouter = () => {
        return useRoutes([
        {
            path: '/home',
            element: 
        },
        ...
    

Communication both frameworks

All right! Now we might ask ourselves a rather spontaneous question:

How can I communicate between a part of my app in angular and one in react or navigate through pages?

The answer? 🥁... : window.postMessage()

The window.postMessage() method safely enables cross-origin communication between a page and an iframe embedded within it

So, we create a function called goTo to navigate across the pages.

    
    function goTo(destination: Destination, params?:
        NavigationParams): void {
        const {parent} = window
        parent.postMessage({
            type: 'navigation',
            state: destination,
            params: params ? params : null
        }, "*")
    }
     

If we send a message from React to Angular, we use this

    
    window.parent.postMessage(
    {
        type: 'UPDATE_ID',
        id: params.id.toString(),
    },
    '*'
    );
    

and then in the Angular controller

    
    window.addEventListener('message', (event) => {
        if (event.data?.type) {
            switch (event.data.type) {
                case 'UPDATE_ID':
                    ctrl.id = event.data.id;
                    break;
            }
        }
    });
    

Conclusion

With this approach, we can integrate React into AngularJS and revitalize it. A good next step would be to rewrite the old AngularJS controllers into React components. This way, we have a smooth transition from AngularJS to React. In the end, we can remove our app-new-wrapper and iframe and delete the old app folder. Then, we will have the whole project in the React framework ✨

See ya next time.👋


Contatta i nostri esperti

per parlare di come possiamo aiutare te e la tua azienda ad evolvere

Contattaci