{"id":29801246,"url":"https://github.com/cisstech/angular-x-react","last_synced_at":"2025-07-28T09:44:20.048Z","repository":{"id":304192515,"uuid":"1018057120","full_name":"cisstech/angular-x-react","owner":"cisstech","description":"This repository is a comprehensive demonstration of bidirectional integration between Angular and React applications within an Nx monorepo. ","archived":false,"fork":false,"pushed_at":"2025-07-11T14:53:47.000Z","size":2581,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-11T16:47:34.361Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cisstech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T14:32:46.000Z","updated_at":"2025-07-11T14:53:51.000Z","dependencies_parsed_at":"2025-07-11T16:57:44.819Z","dependency_job_id":null,"html_url":"https://github.com/cisstech/angular-x-react","commit_stats":null,"previous_names":["cisstech/angular-x-react"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/cisstech/angular-x-react","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisstech%2Fangular-x-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisstech%2Fangular-x-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisstech%2Fangular-x-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisstech%2Fangular-x-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cisstech","download_url":"https://codeload.github.com/cisstech/angular-x-react/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cisstech%2Fangular-x-react/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267496696,"owners_count":24097099,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-28T09:44:16.569Z","updated_at":"2025-07-28T09:44:20.023Z","avatar_url":"https://github.com/cisstech.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Angular and React integration workspace\n\nThis repository is a comprehensive demonstration of bidirectional integration between Angular and React applications within an Nx monorepo. It showcases how to seamlessly use components from one framework within the other, leveraging modern web technologies like custom elements and framework-specific best practices.\n\n## Table of Contents\n\n- [Architecture overview](#architecture-overview)\n- [Project overview](#project-overview)\n- [Key features and benefits](#key-features-and-benefits)\n- [Workspace structure](#workspace-structure)\n- [Getting started](#getting-started)\n  - [Prerequisites](#prerequisites)\n  - [Installation](#installation)\n- [Running the applications](#running-the-applications)\n  - [Exploring the demos](#exploring-the-demos)\n- [How it works](#how-it-works)\n  - [Angular components in React](#angular-components-in-react)\n  - [React components in Angular](#react-components-in-angular)\n- [Build configuration](#build-configuration)\n  - [React components for Angular](#react-components-for-angular)\n  - [Angular components for React](#angular-components-for-react)\n- [Build order for production](#build-order-for-production)\n- [Enabling technologies and concepts](#enabling-technologies-and-concepts)\n  - [Custom elements (web components)](#custom-elements-web-components)\n  - [Dynamic imports and lazy loading with `MutationObserver`](#dynamic-imports-and-lazy-loading-with-mutationobserver)\n  - [Sharing global context and services](#sharing-global-context-and-services)\n  - [CSS handling for React web components](#css-handling-for-react-web-components)\n  - [CSS variables for theming and styling](#css-variables-for-theming-and-styling)\n  - [State management and communication patterns](#state-management-and-communication-patterns)\n  - [Alternative approaches](#alternative-approaches)\n- [Advanced topics and production use cases](#advanced-topics-and-production-use-cases)\n  - [Incremental migration](#incremental-migration)\n  - [Micro-frontends](#micro-frontends)\n  - [Integrating with legacy systems](#integrating-with-legacy-systems)\n  - [Sharing React providers and context](#sharing-react-providers-and-context)\n  - [Optimization tips](#optimization-tips)\n  - [Production considerations: `zone.js` and polyfills](#production-considerations-zonejs-and-polyfills)\n\n## Architecture overview\n\nThe core architectural principle is to maintain a clean separation between the frameworks. Neither application directly depends on the other's source code or packages. Instead, integration is achieved by compiling libraries into framework-agnostic web components (custom elements) and consuming them via simple script tags.\n\nThis approach ensures that you can develop, test, and build each application independently, without creating a complex web of cross-framework dependencies.\n\n```mermaid\ngraph TD\n  subgraph \"React Components in Angular\"\n    A[\"libs/react-for-angular (React Lib)\"] -- \"nx build\" --\u003e B[\"Custom Element Bundle (JS + CSS)\"];\n    B -- \"Output to ➡\" --\u003e C[\"apps/angular/public/webcomponents\"];\n    D[\"apps/angular (Angular App)\"] -- \"Loads script from\" --\u003e C;\n    D -- \"Uses \u003creact-hello-world\u003e\" --\u003e E(\"Renders React Component\");\n  end\n\n  subgraph \"Angular Components in React\"\n    F[\"libs/angular-for-react (Angular App as producer)\"] -- \"nx build\" --\u003e G[\"Custom Element Bundle (JS)\"];\n    G -- \"Output to ➡\" --\u003e H[\"apps/react/public/webcomponents\"];\n    I[\"apps/react (React App)\"] -- \"Loads script from\" --\u003e H;\n    I -- \"Uses \u003cngx-charts\u003e\" --\u003e J(\"Renders Angular Component\");\n  end\n\n  style A stroke:#61DAFB,stroke-width:2px\n  style F stroke:#DD0031,stroke-width:2px\n  style D stroke:#DD0031,stroke-width:2px\n  style I stroke:#61DAFB,stroke-width:2px\n```\n\n- **Angular components in React**: The `angular-for-react` app is built as a standard application, but it also registers its components as custom elements. The `react` app then loads a single JavaScript bundle from the Angular build and can use its components (e.g., `\u003cngx-charts\u003e`) as if they were native HTML elements.\n- **React components in Angular**: Similarly, the `react-for-angular` library is configured with Vite to compile React components into a web component format that the `angular` application can consume.\n\n\n## Project overview\n\nThe primary goal of this workspace is to provide a clear, working example of:\n\n1.  **Angular components in a React app**: Exposing Angular components (including those using third-party libraries) as standard custom elements (web components) and consuming them in React.\n2.  **React components in an Angular app**: Wrapping React components so they can be easily used within an Angular application, complete with property and event binding.\n3.  **Nx monorepo best practices**: Structuring the applications and shared libraries in a clean, maintainable, and scalable way using Nx.\n\n## Key features and benefits\n\n- **Bidirectional integration**: Seamlessly use components across both frameworks.\n- **Clean dependencies**: No cross-framework imports are required, preventing version conflicts and bundling issues.\n- **Standard web components**: The integration is built on web standards, making it future-proof and compatible with other frameworks like Vue or Svelte.\n- **Attribute-based prop passing**: Data is passed to Angular custom elements exclusively through attributes, ensuring robustness and simplicity. Stringified JSON is used for complex objects.\n- **Type-safe usage**: TypeScript declarations are provided for custom elements, enabling full type-safety and autocompletion in the React JSX.\n- **Incremental migration**: This architecture is ideal for gradually migrating a legacy application or integrating micro-frontends from different teams.\n- **Nx-powered**: Built with Nx for powerful code generation, dependency management, and task running.\n\n## Workspace structure\n\nThe monorepo is organized into applications (`apps`) and libraries (`libs`) to maintain a clean separation of concerns.\n\n```text\nangular-x-react/\n├── apps/\n│   ├── angular/              # Main Angular application\n│   │   └── public/           # Hosts compiled React web components\n│   └── react/                # Main React application\n│       └── public/           # Hosts compiled Angular web components\n│\n├── libs/\n│   ├── angular-for-react/    # Source for Angular components exposed as Elements\n│   └── react-for-angular/    # Source for React components exposed as Elements\n│\n└── README.md\n```\n\n| Project                 | Path                               | Description                                                                                                                               |\n| ----------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| `angular`               | `apps/angular/`                    | The primary **Angular application**. It consumes web components built from the `react-for-angular` library.                                 |\n| `react`                 | `apps/react/`                      | The primary **React application**. It consumes web components built from the `angular-for-react` library.                                   |\n| `angular-for-react`     | `libs/angular-for-react/`          | An Angular application project that compiles its components into a standalone bundle of custom elements. It includes logic for lazy-loading and registering these elements for consumption in the React app. |\n| `react-for-angular`     | `libs/react-for-angular/`          | A React library whose components are compiled into custom elements for Angular to use.                                                    |\n\n## Getting started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) (v22 or later recommended)\n- [Yarn](https://yarnpkg.com/) (v4.9 or later)\n\n### Installation\n\n1.  Clone the repository:\n\n  ```sh\n  git clone https://github.com/cisstech/angular-x-react\n  cd angular-x-react\n  ```\n\n2.  Install the dependencies using Yarn:\n\n  ```sh\n  yarn install\n  ```\n\n## Running the applications\n\nYou can run both the Angular and React applications simultaneously to see the integration in action.\n\n### 1. Serve the Angular app\n\nThe Angular app needs to be running to serve the custom elements that the React app will consume.\n\n```sh\nyarn serve:angular\n```\n\nThe Angular application will be available at `http://localhost:4200/`.\n\n### 2. Serve the React app\n\nIn a new terminal, run the React application:\n\n```sh\nyarn serve:react\n```\n\nThe React application will be available at `http://localhost:4201/`.\n\n### Exploring the demos\n\nOnce both applications are running, you can explore the integrations in both directions.\n\n#### Angular components in React demo\n\nNavigate to the **React app** at `http://localhost:4201/`. You will find a dropdown menu to switch between different integration examples:\n\n1.  **Hello world component**: A basic example showing an Angular component (`ngx-hello-world`) that accepts a `name` string attribute from React. You can type into the input field in the React UI, and the change is instantly reflected in the Angular component.\n2.  **NGX-Charts component**: A more advanced example demonstrating an Angular component (`ngx-charts`) that uses the popular `@swimlane/ngx-charts` library. This component receives its configuration and data as stringified JSON attributes, showcasing how to pass complex objects from React to an Angular custom element.\n\n#### React components in Angular demo\n\nNavigate to the **Angular app** at `http://localhost:4200/`. Here you will see a React component (`\u003creact-hello-world\u003e`) rendered inside the Angular application. This demonstrates the reverse integration, where a React component, compiled as a custom element, is seamlessly used within Angular.\n\n#### Live demo on GitHub Pages\n\nGo to the [GitHub Pages demo](https://cisstech.github.io/angular-x-react/) to see react and angular apps in action without needing to run the applications locally.\n\n## How it works\n\n### Angular components in React\n\n1.  **Creation**: Angular components are created as usual (e.g., `NgxChartsComponent`). They use Angular's `signal` inputs to receive data.\n2.  **Registration**: In `apps/angular/src/main.ts`, Angular's `createCustomElement` function from `@angular/elements` is used to wrap the Angular components into custom elements.\n3.  **Consumption**: In the React app (`apps/react/src/app/app.tsx`), the custom elements (`\u003cngx-hello-world\u003e`, `\u003cngx-charts\u003e`) are used like regular HTML tags. The components are made available because the compiled Angular script is loaded in `apps/react/index.html`.\n4.  **Data passing**: Props are passed as attributes. For complex objects (like chart data), the React app uses `JSON.stringify()` to pass the data as a string, and a custom `coerceObject` utility on the Angular side parses it back into an object.\n5.  **Type safety**: A `global.d.ts` file in the React app declares the custom elements and their attributes to JSX, providing type checking and IntelliSense.\n\n### React components in Angular\n\nThe `react-for-angular` library is set up to facilitate this. The process involves:\n\n1.  Creating a React component.\n2.  Using the `register` utility in the library to wrap the React component, making it available to Angular.\n3.  Consuming the wrapped component in an Angular template.\n\n## Build configuration\n\nThe magic of this integration lies in the build configuration. Each framework's build process is set up to place its compiled output directly into the `public` directory of the consuming application. This ensures that the web components are available at runtime without complex module federation or linking.\n\n### React components for Angular\n\nThe `react-for-angular` library uses a custom Vite configuration to build its React components and output them directly into the Angular app's public assets directory.\n\nHere is the relevant section from `libs/react-for-angular/vite.config.ts`:\n\n```typescript\n// libs/react-for-angular/vite.config.ts\n\nexport default defineConfig(() =\u003e ({\n  // ... other config\n  build: {\n  // This is the crucial part:\n  // The output directory is set to the 'public' folder of the Angular app.\n  outDir: '../../apps/angular/public/react-for-angular',\n  emptyOutDir: true,\n  // ...\n  rollupOptions: {\n    input: 'src/index.ts',\n    output: {\n    // I specify a fixed output filename to make it easy to reference\n    // in Angular's index.html.\n    entryFileNames: 'index.js',\n    format: 'esm',\n    // ...\n    },\n  },\n  },\n  // ...\n}));\n```\n\nThis configuration tells Vite to compile the React components into a single JavaScript file and place it at `apps/angular/public/react-for-angular/index.js`. The Angular app can then load this script like any other static asset.\n\n### Angular components for React\n\nA similar strategy is used for the Angular components. The `angular` application's build configuration in `project.json` is modified to place the compiled custom elements into the React app's `public` directory.\n\nHere is the relevant section from `apps/angular/project.json`:\n\n```json\n// apps/angular/project.json\n\n{\n  \"name\": \"angular\",\n  // ...\n  \"targets\": {\n  \"build\": {\n    \"executor\": \"@angular/build:application\",\n    \"outputs\": [\"{options.outputPath}\"],\n    \"options\": {\n      // The output path is redirected to the React app's public folder.\n      \"outputPath\": {\n        \"base\": \"apps/react/public/webcomponents\",\n        \"browser\": \"\"\n      },\n      \"browser\": \"apps/angular/src/main.ts\",\n      // ...\n    },\n    \"configurations\": {\n    \"production\": {\n      // In production, output hashing is enabled to ensure unique filenames\n      // for cache-busting.\n      \"outputHashing\": \"all\"\n    },\n    \"development\": {\n      // In development, hashing is disabled for predictable filenames.\n      \"outputHashing\": \"none\"\n    }\n    },\n    // ...\n  }\n  }\n}\n```\n\nThis setup ensures that when you build the `angular` app, its output (the JavaScript bundle containing the custom elements) is placed in `apps/react/public/angular-for-react/`. The React app's `index.html` can then include this bundle with a simple `\u003cscript\u003e` tag, making the Angular components available for use.\n\n## Build order for production\n\nTo create production-ready bundles for the applications and libraries, you must build them in the correct order: **producers first, then consumers**.\n\n1.  **Build the `react-for-angular` library**: This creates the web components for the Angular app.\n\n  ```sh\n  yarn build:react-for-angular\n  ```\n\n2.  **Build the `angular-for-react` app**: This creates the web components for the React app.\n\n  ```sh\n  yarn build:angular-for-react\n  ```\n\n3.  **Build the `angular` application**: This creates the web components for the React app.\n\n  ```sh\n  yarn build:angular\n  ```\n\n4.  **Build the `react` application**: This builds the final React app, which now includes the Angular components.\n\n  ```sh\n  yarn build:react\n  ```\n\nAfter running these commands, the `dist/` folder will contain the production-ready applications.\n\n## Enabling technologies and concepts\n\nThis repository demonstrates a powerful pattern for framework interoperability, relying on a combination of modern web standards and smart build configurations.\n\n### Custom elements (web components)\n\nThe core of the integration lies in [custom elements](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements), a part of the web components specification. Both Angular and React components are wrapped as custom elements, which are framework-agnostic HTML tags.\n\n- **In React (`react-for-angular`)**: I use a lightweight wrapper around `ReactDOM.createRoot()` to render a React component inside a custom element's shadow DOM. This encapsulates the component's logic, template, and styles.\n- **In Angular (`angular-for-react`)**: Angular's `@angular/elements` package provides the `createCustomElement()` function to transform an Angular component into a custom element.\n\nThis approach ensures that from the outside, a component behaves like a standard HTML element, regardless of the framework that built it.\n\n### Dynamic imports and lazy loading with `MutationObserver`\n\nTo avoid loading all JavaScript bundles upfront, this repository implements a lazy-loading mechanism. The initial bundles for the main Angular and React apps include their respective core framework packages but *not* the custom elements from the other framework. Instead of directly including script tags for the web components, the host application dynamically loads the component bundles only when they are actually needed.\n\nThis is achieved using a `MutationObserver`:\n\n- **On the Angular side**: The `ElementLoaderService`, used in the root `AppComponent`, sets up a `MutationObserver` to watch the DOM. When it detects a custom element tag (e.g., `\u003creact-hello-world\u003e`), it dynamically imports the corresponding JavaScript bundle.\n- **On the React side**: The logic is encapsulated within the `defineLazyReactComponent` function. This function creates a wrapper web component that, when connected to the DOM, uses a dynamic `import()` to fetch the React component's code.\n\nOnce loaded, the script executes and formally defines the custom element using `customElements.define()`, which upgrades the placeholder tag into a fully interactive component. This \"just-in-time\" loading strategy is highly efficient, as it ensures that users only download the code for the components they interact with.\n\n### Sharing global context and services\n\n- **Angular services**: Angular components exposed as custom elements can still inject and use global services provided in the root Angular application, as they are part of the same dependency injection tree.\n- **React context**: Global React context providers can be configured from the `defineLazyReactComponent` function. When the component is rendered, it can be wrapped with any necessary providers (for theming, state management, etc.), making the context available to the component.\n\n### CSS handling for React web components\n\nStyling web components, especially across framework boundaries, requires careful handling. When a React component is bundled as a library for use in Angular, its CSS needs to be loaded correctly.\n\nI use a special configuration in `libs/react-for-angular/vite.config.ts` to manage this:\n\n```typescript\n// libs/react-for-angular/vite.config.ts\nexport default defineConfig(() =\u003e ({\n  // ...\n  experimental: {\n  renderBuiltUrl(filename, { hostType }) {\n    if (hostType === 'js' \u0026\u0026 filename.endsWith('.css')) {\n    // Rewrite the path to the CSS file to be relative to the JS entry point\n    return {\n      runtime: `new URL('assets/${filename.split('/').pop()}', import.meta.url).href`,\n    };\n    }\n    return { relative: true };\n  },\n  },\n}));\n```\n\n**What this does:**\n\nThe `renderBuiltUrl` function intercepts the way Vite handles asset URLs during the build. When the JavaScript part of the build (`hostType === 'js'`) references a CSS file, I modify the runtime code that Vite generates.\n\nInstead of a static path, I generate `new URL('...', import.meta.url).href`. This creates a fully resolved URL for the CSS file *relative to the location of the JavaScript file that is importing it*. This is critical because the JavaScript bundle will be loaded by the Angular application from its `public/webcomponents` directory, and it needs to know how to find its own CSS assets from there.\n\n### CSS variables for theming and styling\n\nTo create a consistent look and feel across components from different frameworks, I use **CSS custom properties (variables)**.\n\n- A set of global CSS variables is defined in the host application (e.g., in Angular's `styles.scss`).\n- These variables control common theme elements like primary colors, font sizes, spacing, etc.\n- Both Angular and React components consume these variables for their styling.\n\nBecause custom elements can inherit CSS variables from their parent document, this is a simple yet powerful way to achieve a unified design system without complex style sharing or configuration.\n\n### State management and communication patterns\n\nA robust integration requires clear communication patterns. The custom element approach encourages a clean, unidirectional data flow that is easy to reason about.\n\n- **Props down**: The consuming application always owns the state. Data is passed *down* to a web component via its HTML attributes.\n    - **From Angular to React**: Props are passed using attribute binding (e.g., `[attr.name]=\"data\"`). The `defineLazyReactComponent` utility parses these attributes, including JSON-stringified values, into React props.\n    - **From React to Angular**: Standard React prop syntax is used (e.g., `name=\"World\"`). For complex data like objects or arrays, serialize them to a string with `JSON.stringify()` before passing them. The web component on the Angular side is then responsible for parsing this string.\n- **Events up**: To communicate *up* from a web component to the consumer, use standard DOM `CustomEvent`s. The component can dispatch an event, and the consuming application can add an event listener to react to it. This prevents the web component from having any direct knowledge of its parent's framework or state management library.\n\nThis \"props down, events up\" model is a universal pattern that works across all frameworks and ensures your components remain decoupled and reusable.\n\n### Alternative approaches\n\nWhile this repository champions the custom element approach, it's helpful to understand how it compares to other common integration strategies.\n\n| Strategy              | Pros                                                                                             | Cons                                                                                                                            | Best For                                                                                             |\n| --------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |\n| **Custom elements**   | **Web standard**, framework-agnostic, good encapsulation, simple \"props down, events up\" model.    | Can have a slight performance overhead for bootstrapping the framework (e.g., React) inside the element.                      | **This repo's choice**: Micro-frontends, incremental migration, design systems.                      |\n| **Module federation** | Powerful, allows runtime sharing of dependencies, potentially smaller user downloads.              | Complex configuration, can lead to tight coupling, versioning challenges between frameworks.                                    | Large, complex applications where multiple teams need to share code and dependencies at runtime.     |\n| **iframes**           | **Maximum isolation** (styles, scripts, globals are completely separate), simple to set up.        | Clunky communication (`postMessage`), poor for deep UI integration, can feel disconnected, potential SEO issues.              | Embedding third-party widgets or applications where deep integration is not required.                |\n\nThe **custom element** approach was chosen for this project because it offers the best balance of integration and isolation, is built on stable web standards, and provides a clear, scalable path for both migrating legacy systems and building modern micro-frontend architectures.\n\n## Advanced topics and production use cases\n\nThe patterns in this repository are not just for demos; they are robust enough for complex, real-world applications. Here are some ways you can leverage this architecture:\n\n### Incremental migration\n\nThis setup is ideal for incrementally migrating a legacy application. If you have a large Angular application, you can start writing new features as React web components and embed them. Over time, you can gradually replace existing Angular components with their React counterparts, one by one, without a \"big bang\" rewrite. The `MutationObserver` pattern ensures that the performance impact is minimal.\n\n### Micro-frontends\n\nThis monorepo can serve as the foundation for a micro-frontend architecture. Each application or library can be owned by a different team.\n\n- The `angular` app could act as the \"shell\" or \"host\" application.\n- `react-for-angular` and other similar libraries could be micro-frontends that expose specific business capabilities.\n- Since the integration contract is based on standard custom elements, teams can develop and deploy their micro-frontends independently.\n\n### Integrating with legacy systems\n\nHave an old jQuery or server-rendered application? You can still use this pattern. As long as you can add a `\u003cdiv\u003e` and a `\u003cscript\u003e` tag to the page, you can introduce a `MutationObserver` to lazy-load modern Angular or React components into your legacy system, providing a clear path for modernization.\n\n### Sharing React providers and context\n\nA common challenge with React web components is sharing state or context, as each component is typically rendered in its own isolated React root. To solve this, you can design a \"container\" web component that is responsible for setting up all the necessary React `Context.Provider`s. Other \"child\" components can then be rendered within it and consume the shared context. This requires careful orchestration but is a valid pattern for complex interactions between multiple React micro-frontends on the same page.\n\n### Optimization tips\n\n- **External configuration**: For maximum flexibility, the mapping between custom element tags and their bundle URLs can be externalized into a JSON configuration file instead of being hardcoded in the `MutationObserver` script. This allows you to update component versions or paths without redeploying the host application.\n- **Shared dependencies**: While `vite` and `webpack`... are good at tree-shaking, analyze your final bundles to see if `react`, `react-dom`, or other large libraries can be treated as true externals and loaded only once on the page instead of being in the initial bundle.\n\n### Production considerations: `zone.js` and polyfills\n\nWhen moving this architecture to production, there are two important considerations for ensuring robustness and performance.\n\n#### Running Angular without `zone.js`\n\nFor better performance and to avoid side effects in a multi-framework environment, you can bootstrap Angular without `zone.js` (like in the demo app). This prevents Angular from patching global asynchronous APIs, which can interfere with other libraries or frameworks.\n\nTo do this, you would typically modify your `app.config.ts` file:\n\n```typescript\n// app.config.ts\nimport {\n  provideZonelessChangeDetection,\n} from '@angular/core';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    provideZonelessChangeDetection(),\n  ],\n};\n```\n\n**Implication**: When you run without `zone.js`, Angular's automatic change detection will not trigger on asynchronous events. You will need to manually trigger change detection within your components when their state changes (e.g., by injecting `ChangeDetectorRef` and calling `cdr.detectChanges()`).\n\n#### Browser support and polyfills\n\nCustom elements are widely supported in all modern browsers. However, if you need to support older browsers that lack native support, you may need to include a polyfill. The most common one is from the webcomponents.js project.\n\nYou can install it via npm:\n```sh\nnpm install @webcomponents/custom-elements\n```\nAnd then include it in your application's build process, typically in the `polyfills.ts` file for an Angular app or at the top of your entry file for a React app.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcisstech%2Fangular-x-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcisstech%2Fangular-x-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcisstech%2Fangular-x-react/lists"}