Guide · AngularJS migration
AngularJS to React with the strangler pattern
By MervenorPublished Last reviewed 4 min read
AngularJS has had no official fixes since its long-term support ended on 31 December 2021, and new vulnerabilities are still being published for it. A rewrite that freezes the product for months is rarely necessary: run React beside AngularJS, move one route or screen at a time, and delete the old code as you go. The product keeps shipping, and every step can be undone.
Why move now
Google ended long-term support for AngularJS on 31 December 2021; the code repositories are archived and the packages are marked as deprecated. Vulnerabilities kept being found afterwards: one extended-support vendor lists at least eight CVEs published since the end of support, among them CVE-2024-8372 and CVE-2025-0716, that the open-source releases will never fix. Add the shrinking pool of developers who want to work on AngularJS and the libraries that have dropped it, and the cost of staying grows every quarter.
React or modern Angular?
Both are sound destinations. Modern Angular offers an official bridge, ngUpgrade, which runs AngularJS and Angular in one hybrid application, and it suits teams who like Angular's structure. React has no official bridge, but the strangler pattern below works well, and React suits teams who already use it elsewhere or plan to move to Next.js. Choose by the skills you have and the rest of your stack, not by fashion.
The strangler pattern for front ends
The old and new front ends run together in the same browser session, on the same domain, sharing sign-in. Two ways to split the work, often combined:
- By route: a thin shell (or the web server) decides, URL by URL, whether React or AngularJS renders the page. Moving a route means changing one rule.
- By component: React components are mounted inside existing AngularJS screens through a small wrapper directive, so a heavy widget can move before its page does. Frameworks such as single-spa formalise this, with "parcels" that mount a component from one framework inside another.
Step by step
Freeze the behaviour.
Write end-to-end tests (Playwright or Cypress) for the journeys that earn money or cause support tickets. They are your safety net for every later step.
Build the React shell.
Same domain, same sign-in cookie or session, same design tokens, so a user cannot tell which framework drew the page.
Add the route switch.
Start with one simple, low-risk route to prove the build, the deploy and the switch.
Agree the contract between the two worlds.
Use the URL and a small event bus or shared store; avoid letting React reach into
$scopeor AngularJS reach into React state.Move routes one at a time.
Each move ships on its own, behind a flag if needed, with its tests passing; the way back is switching the route back.
Delete as you go.
Remove each AngularJS controller, template and service as soon as its route has moved, and watch the bundle shrink.
Remove AngularJS.
When the last route has moved, drop the library, the wrapper directives and the old build, then tighten the content security policy.
See it done: our public reference migration moves angular-phonecat, the official AngularJS tutorial application, to React and TypeScript one tagged step at a time, with the behaviour tests green at every step (github.com/mervenor/angularjs-to-react-reference).
What makes it hard
- Logic hidden in the digest cycle and in
$scopeinheritance between nested controllers. - Directives that manipulate the DOM directly.
- Global events on
$rootScopeand services that hold shared state. - Routing with
ui-router, especially nested and abstract states. - Forms and validation, which behave differently in React.
- Sparse tests, which is why step 1 comes first.
Keeping search rankings
If the application has public pages, keep every URL where it is, render the content on the server or prerender it where search matters, and add a permanent redirect in the same release whenever a URL must change.
Questions people ask
How long does it take?
It depends on the number of routes and screens, how much logic sits in directives and the digest cycle, and how much is covered by tests. Because routes move one at a time, value arrives from the first weeks rather than at the end.
Can we keep shipping features during the migration?
Yes. New features are written in React from the start; that is one of the main reasons to choose the strangler pattern.
Can we buy time instead?
Sometimes. Moving to the last AngularJS release or to paid extended support can buy time, but it does not remove the need to migrate.
Renascia, the upgrade and migration sprint, moves AngularJS applications to React or modern Angular route by route, at a fixed price set by a five-day Perlustra audit.