As a developer, I’ve often hit a specific roadblock. Sometimes, a specialized team builds a complex dashboard in Angular, and you need that exact functionality in your React-based consumer app.
I remember once needing to port a complex mortgage calculator built in Angular into a new React portal for a California-based lender.
That is when I started exploring how to wrap Angular components so they could live happily inside a React environment.
In this tutorial, I will show you exactly how to bridge the gap between these two powerful frameworks using proven, real-world methods.
Mix Angular and React
In large-scale US enterprise environments, different departments often choose different tech stacks based on their specific needs.
You might find yourself in a situation where a legacy “Internal Admin” tool is in Angular, but the “Customer Facing” site is React.
Instead of maintaining two separate codebases for the same UI logic, you can share components across the organizational silos.
It also helps significantly during “Micro-Frontend” migrations, where you are slowly moving a massive application from Angular to React.
Method 1: Use Custom Elements (Web Components)
This is my favorite approach because it relies on the browser’s native capabilities rather than a third-party hack.
Angular allows us to package a component as a “Custom Element” (Web Component) using the @angular/elements package.
Once it is a Web Component, React treats it just like a standard HTML tag like <div> or <section>.
Step 1: Prepare the Angular Component
Imagine we have a US Tax Bracket Calculator component in Angular. First, we need to convert it.
// Angular Component: tax-calculator.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-tax-calculator',
template: `
<div style="border: 2px solid #00447c; padding: 20px; border-radius: 8px;">
<h3>IRS Tax Estimator (2024)</h3>
<p>Annual Income: {{ annualIncome | currency:'USD' }}</p>
<button (click)="calculate()">Estimate Federal Tax</button>
</div>
`,
styles: [`h3 { color: #00447c; }`]
})
export class TaxCalculatorComponent {
@Input() annualIncome: number = 0;
@Output() onCalculate = new EventEmitter<number>();
calculate() {
// Simplified US Federal Tax Logic
const estimatedTax = this.annualIncome * 0.22;
this.onCalculate.emit(estimatedTax);
}
}Now, we define it as a custom element in the Angular module:
// app.module.ts
import { NgModule, Injector } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
import { TaxCalculatorComponent } from './tax-calculator.component';
@NgModule({
declarations: [TaxCalculatorComponent],
imports: [BrowserModule]
})
export class AppModule {
constructor(private injector: Injector) {}
ngDoBootstrap() {
const el = createCustomElement(TaxCalculatorComponent, { injector: this.injector });
customElements.define('tax-calculator-element', el);
}
}Step 2: Consume it in React
In your React project (e.g., a Boston-based Wealth Management app), you first need to import the compiled Angular script.
Then, you can use the tag directly. Since React’s synthetic events don’t always catch Custom Element events, I use a ref.
// React Component: Dashboard.js
import React, { useEffect, useRef, useState } from 'react';
const MortgageDashboard = () => {
const [tax, setTax] = useState(0);
const calculatorRef = useRef(null);
const income = 95000; // Average salary for a Senior Dev in Texas
useEffect(() => {
const currentRef = calculatorRef.current;
// Listen for the custom event emitted by Angular
const handleEvent = (event) => {
setTax(event.detail);
};
if (currentRef) {
currentRef.addEventListener('onCalculate', handleEvent);
}
return () => {
if (currentRef) {
currentRef.removeEventListener('onCalculate', handleEvent);
}
};
}, []);
return (
<div style={{ family: 'Arial', padding: '40px' }}>
<h1>Client Financial Overview</h1>
<p>Location: Chicago, IL</p>
{/* The Angular Component used as a Web Component */}
<tax-calculator-element
ref={calculatorRef}
annual-income={income}
/>
{tax > 0 && (
<div style={{ marginTop: '20px', fontWeight: 'bold' }}>
Estimated Federal Tax Liability: ${tax.toLocaleString()}
</div>
)}
</div>
);
};
export default MortgageDashboard;You can see the output in the screenshot below.

Method 2: Use a Manual Bootstrapping Wrapper
In some cases, you might not want to deal with Web Components or Polyfills for older browsers like those still used in some US government offices.
You can manually bootstrap an Angular application into a specific DOM node managed by React.
This feels a bit more “manual,” but it gives you total control over the Angular lifecycle inside React.
The Angular Setup
You need to ensure your Angular component is exportable and that you have a function to start it.
// main.ts (Angular side)
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
export function mountAngularApp(containerId: string) {
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
}The React Wrapper
In React, we create a “container” component. When it mounts, it triggers the Angular bootstrap function.
// React Component: AngularWrapper.js
import React, { useEffect } from 'react';
const AngularWrapper = () => {
useEffect(() => {
// Assuming the Angular bundle is already loaded in the global window
if (window.mountAngularApp) {
window.mountAngularApp('angular-app-root');
}
}, []);
return (
<div className="container mt-5">
<div className="card">
<div className="card-header bg-primary text-white">
Integrated Angular Service - US Healthcare Portal
</div>
<div className="card-body">
{/* Angular will render inside this ID */}
<div id="angular-app-root"></div>
</div>
</div>
</div>
);
};
export default AngularWrapper;Challenges I Encountered (And How to Fix Them)
When I first implemented this for a retail client in Seattle, I ran into two major issues: CSS Clashes and Change Detection.
Handle CSS Clashes
Angular usually uses Emulated View Encapsulation, which is great. However, global styles from your React Bootstrap theme might leak into Angular.
I recommend using Shadow DOM in your Angular component settings to completely isolate the styles.
@Component({
selector: 'app-tax-calculator',
templateUrl: './tax-calculator.component.html',
encapsulation: ViewEncapsulation.ShadowDom // This is the secret sauce
})Prop Synchronization
React only passes strings to attributes of Custom Elements by default.
If you need to pass an object (like a complex US Insurance Policy object), you must set the property directly on the DOM node via a ref.
useEffect(() => {
if (calculatorRef.current) {
// Passing a complex object instead of a string
calculatorRef.current.policyData = {
state: 'Florida',
type: 'PPO',
coverage: 500000
};
}
}, []);Performance Considerations for US Users
High-speed internet is common in the US, but mobile users in rural areas still struggle with large bundle sizes.
Loading both the React runtime and the Angular runtime can make your page heavy (over 500KB easily).
I suggest using Lazy Loading in React. Only load the Angular scripts when the user navigates to the specific part of the app that needs it.
You can use React.lazy() or simply dynamic import() statements to fetch the Angular “main.js” bundle on demand.
Summary of Key Differences
| Feature | Custom Elements Method | Manual Bootstrap Method |
| Ease of Use | High (Once set up) | Medium |
| Browser Support | Modern Browsers (Needs Polyfills) | High |
| Communication | Events & Refs | Global Window/Services |
| Best For | Reusable UI Library | Large Modules/Micro-frontends |
Using Angular components in React is a powerful technique when handled correctly.
It allows US-based dev teams to collaborate better and reuse existing, battle-tested logic without expensive rewrites.
I have found that while it takes a bit of initial configuration, the long-term maintenance savings are worth the effort.
Whether you are working on a banking app in New York or a tech startup in Austin, this bridge will save you weeks of development time.
You may also like to read:
- How to Use a For Loop in React Functional Components
- How to Convert React Component to TypeScript
- React Pass Function to Child Component
- React Controlled Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.