<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luís Takahashi</title>
    <description>The latest articles on DEV Community by Luís Takahashi (@luistak).</description>
    <link>https://dev.to/luistak</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F246129%2F6284e397-c3eb-4dd5-82d5-ab2ee330a4cc.jpg</url>
      <title>DEV Community: Luís Takahashi</title>
      <link>https://dev.to/luistak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/luistak"/>
    <language>en</language>
    <item>
      <title>The Software Entropy in the AI Era</title>
      <dc:creator>Luís Takahashi</dc:creator>
      <pubDate>Wed, 14 Oct 2026 19:01:39 +0000</pubDate>
      <link>https://dev.to/luistak/the-software-entropy-in-the-ai-era-1ok7</link>
      <guid>https://dev.to/luistak/the-software-entropy-in-the-ai-era-1ok7</guid>
      <description>&lt;p&gt;TL;DR: I ran an experiment with AI-augmented development. In one month we produced 400k+ lines of code, 150 features, 240 fixes and 50 refactors, then the entropy accelerated and the velocity collapsed. What normally takes years of accumulated technical debt across multiple teams happened in weeks.&lt;/p&gt;




&lt;p&gt;Hi there, my name is Takah, I'm a Principal Software Engineer from Brazil. In the past months I've been conducting a few experiments on how to adapt our SDLC and explore new ways of working with AI, both enabling non-engineers to code in our repos and also enhancing every guard-rail, guideline and common market standards to support this type of workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Software Entropy?
&lt;/h2&gt;

&lt;p&gt;But let's circle back to the title of this article: what is Software Entropy? First of all, what is entropy? I'll freely give one interpretation that entropy, borrowed from thermodynamics, is the natural tendency toward disorder or uncertainty in a system, and what is exactly software entropy? I'd say its the natural tendency of any given software and system to disorder, when new features are being added, new modules, new fixes, quick-wins, a hacky solution to fix or deliver something in time, or to prevent another incident, regardless of the most architectural pre-definition and future-proof hexagonal multi-flexible, composable and any other blazingly fast buzzword you wanna add, it's impossible to predict and prevent all use-cases beforehand, that's why entropy always end up happening.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entropy is not a bug, it's a fundamental property of any system that grows. The question is never if it will happen, its how fast, and whether you have the mechanisms to manage it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Does AI Have to Do With Software Entropy?
&lt;/h2&gt;

&lt;p&gt;And what AI has to do with Software Entropy? Like i said one of the experiments i did was me a Software engineer and 2 other designers, which we had the challenge of developing a whole new experience of a chat and we wanted to leverage the AI ecosystem at its maximum.&lt;/p&gt;

&lt;p&gt;So first, before any line of code, i aligned the scope, contracts, and overall architecture of the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tech stack&lt;/li&gt;
&lt;li&gt;Repository setup, code structure, architectural guidelines&lt;/li&gt;
&lt;li&gt;AI guidelines: agents, skills, context files for testing, styling, developing new features, feature-branches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And after the initial setup we had, and helping them setup their own setup with claude, our internal ai-proxy, repository, vpns, etc we started developing. And at the beginning it was awesome. The guidelines and setup were satisfactory, features seemed to be right, we were adding one feature after another with autonomy, tests, coverage, and apparently following the project guidelines.&lt;/p&gt;

&lt;p&gt;But whats the problem?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Turn: Week Three
&lt;/h2&gt;

&lt;p&gt;After 3 weeks we had a codebase with more than 400k lines, dozens of features, animations, micro-interactions that would maybe take several sprints to be made if they were handcrafted by a team of engineers. But at this moment things started to break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each feature velocity started to decline&lt;/li&gt;
&lt;li&gt;New behaviours that interacted with previous states started to skyrocket race-conditions&lt;/li&gt;
&lt;li&gt;One new feature broke 3 other working ones&lt;/li&gt;
&lt;li&gt;A simple feature that previously took a few hours now took days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And we had to circle back and analyze what was happening.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The guidelines and guard-rails that were previously added were not enough, because even with a strict guideline saying to our models and setup: "Use X technology or Y Architecture or Z state management tool in this way," the probabilist nature of LLMs still were delusional.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We had several features that reimplemented different state machines, did full animations, sound, charts from scratch while it was already solved in a sibling part of the application, and one of the signs were the codebase growth, it was exponentially growing in number of lines and files.&lt;/p&gt;

&lt;p&gt;To give you a sense of the scale, in roughly one month we accumulated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;150 features&lt;/strong&gt; added&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;240 fixes&lt;/strong&gt; applied&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;50 refactors&lt;/strong&gt; performed, with refactors as large as removing more than &lt;strong&gt;50k lines of code in a single one&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I'm not alone in this, the data from 2026 tells the same story across the industry. The &lt;a href="https://dora.dev/insights/balancing-ai-tensions/" rel="noopener noreferrer"&gt;2025 DORA State of AI-assisted Software Development report&lt;/a&gt; found that a 25% increase in AI adoption is associated with a &lt;a href="https://dora.dev/ai/gen-ai-report/report/" rel="noopener noreferrer"&gt;7.2% decrease in delivery stability&lt;/a&gt;, because AI allows developers to generate code much faster and it often leads to larger batch sizes, which are slower to review and more prone to creating system instability. &lt;a href="https://newrelic.com/pt/press-release/20260623-1#1" rel="noopener noreferrer"&gt;New Relic's 2026 State of AI Coding report&lt;/a&gt;, which surveyed 200 technology leaders, found that while 94% of them rate AI-generated code as higher quality at review time, 78% report more incidents once it ships and 82% experienced at least one production failure tied to AI-generated code in the past six months. They call this &lt;a href="https://newrelic.com/jp/blog/news/new-relic-now-june-2026-round-up#1" rel="noopener noreferrer"&gt;agent debt&lt;/a&gt;, the rapid accumulation of unvetted architectural logic that triggers production incidents down the line. And a &lt;a href="https://zenodo.org/records/20259154#1" rel="noopener noreferrer"&gt;systematic review of 34 studies&lt;/a&gt; covering 2,847 developers found that technical debt principal increased by 1.8 person-days per 1,000 AI-generated lines of code, with the debt ratio doubling within 6 months without mitigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: Tightening the Guard-Rails
&lt;/h2&gt;

&lt;p&gt;To fix that we had to do several fixes, refactors, and with each fix and refactor to strictly tighten the guard-rails, tests, and add custom deterministic tools to truly ensure that the code was following each guideline. In practice this meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI guard-rails in agents:&lt;/strong&gt; direct instructions, specific skills and context files that enforced architectural patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic tools:&lt;/strong&gt; lint rules, pipeline validations and custom checks that verified architectural conformance before merge&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict refactoring cycles:&lt;/strong&gt; regular mandatory refactoring capacity to reduce the debt principal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expert oversight:&lt;/strong&gt; a specialized developer actively enhancing the guidelines, understanding what to use, what not to use, how to fix, and correcting the AI to follow new strict rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end result the AI usage was a success, within a month we developed something that would take months to be made handcrafted, but at what cost?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a specialized developer was not present enhancing the guidelines, understanding what to use, what not to use, how to fix, and actively enhancing its guard-rails this codebase was doomed to failure. Or maybe a full refactor or depriorization due to the effort of maintaining it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Exponential Decline of the Codebase
&lt;/h2&gt;

&lt;p&gt;So whats my conclusion? All that happening within a month its the same thing i saw happening during years of a codebase, it normally takes months of multiple developers, teams, and technical debts accumulated to reach the same level of entropy and disorder where each new feature was breaking 3 others. What I'm calling the exponential decline of the codebase is not just a metaphor, its what happens when the rate of entropy generation outpaces the rate of human oversight by an order of magnitude.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="https://www.computer.org/publications/tech-news/trends/protect-code-from-broken-ai-software#1" rel="noopener noreferrer"&gt;IEEE Computer Society&lt;/a&gt; puts it bluntly: "Standing between such problematic AI output and other downstream disasters? Software engineers. The value of engineers with the software lifecycle knowledge needed to guide and oversee AI assistants and their output is immeasurable."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;a href="https://zenodo.org/records/19700282" rel="noopener noreferrer"&gt;arXiv paper "Beyond the 'Diff'&lt;/a&gt;" defines agentic entropy as "a systemic drift that traditional code diff-based and HCXAI methods fail to capture, as they address local outputs rather than global agentic behaviour," and notes that "functional checks (e.g., confirming that the code runs) can thus mask deeper architectural violations and security gaps, producing an illusion of rapid progress while drift accumulates beneath the surface."&lt;/p&gt;

&lt;p&gt;The AI era is awesome, but without proper follow-up and deep specialized people understanding whats being written and which software engineering strategies, architecture and design patterns to follow, it will exponentially increase the software entropy. &lt;a href="https://www.gartner.com/en/newsroom/press-releases/2026-07-07-gartner-predicts-60-percent-of-organizations-will-adopt-smaller-software-engineering-teams-by-2029" rel="noopener noreferrer"&gt;Gartner predicts&lt;/a&gt; that by 2029, 60% of organizations will adopt smaller software engineering teams at scale, up from 15% in 2026. But smaller teams with AI does not mean no engineers, it means engineers with different skills, architects, overseers, guard-rail builders. The &lt;a href="https://www.acm.org/media-center/2026/april/techbrief-vibe-coding" rel="noopener noreferrer"&gt;ACM Technology Policy Council's TechBrief on vibe coding&lt;/a&gt; warns that it "often skips over core engineering practices that ensure systems are secure, reliable, and maintainable," and their lead author Simson Garfinkel says it directly: "It's making developers dramatically more effective, but it's also introducing security vulnerabilities, increasing technical debt, and producing code that can be difficult to maintain."&lt;/p&gt;

&lt;h2&gt;
  
  
  A Reflection for Engineering Leaders
&lt;/h2&gt;

&lt;p&gt;If you're a manager, head of engineering, VP or CTO reading this, i want you to reflect on a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How are you aspiring your org to be? Are you designing for a future where AI does the coding and engineers do the oversight, or one where engineers use AI as a tool while retaining architectural ownership?&lt;/li&gt;
&lt;li&gt;Where are your gaps? Do you have mechanisms to detect software entropy as it accumulates, deterministic guard-rails and not just guidelines, engineers who can recognize when the AI is drifting from architectural intent?&lt;/li&gt;
&lt;li&gt;Whats your oversight model? The data from New Relic shows that &lt;a href="https://newrelic.com/jp/blog/news/new-relic-now-june-2026-round-up#1" rel="noopener noreferrer"&gt;62% of technology leaders&lt;/a&gt; report their teams trust AI-generated code enough to ship it to production without line-by-line manual verification, is that a risk you're willing to take?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Disclosure on AI
&lt;/h2&gt;

&lt;p&gt;In that way, i don't dislike Agentic Coding, neither the idea of non-engineers coding, my conclusion is that the current state of ai tools are not ready yet to be driven by full Ai enthusiasts, software engineers are going to exist, this is the new normal we should not fear Ai we should embrace these new tools and understand how we could be more productive and have more time to focus in new strategies, features, design patterns, career, our mental and physical health and our familly not only delivering more value to our shareholders.&lt;/p&gt;

&lt;p&gt;The illusion that a single person with AI can replace a team of engineers is just that, an illusion. What we experienced in one month is what happens when you remove the expertise from the loop. The entropy accelerates, the velocity collapses, and the cost compounds. Software engineers are still necessary, the question is, are we building organizations that know how to use them?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>⚔️ Cross micro frontends communication 📦</title>
      <dc:creator>Luís Takahashi</dc:creator>
      <pubDate>Sat, 10 Oct 2020 23:23:53 +0000</pubDate>
      <link>https://dev.to/luistak/cross-micro-frontends-communication-30m3</link>
      <guid>https://dev.to/luistak/cross-micro-frontends-communication-30m3</guid>
      <description>&lt;p&gt;In this article, I'm going to explain some ways to communicate between multiple applications and a particular way that I have chosen to use in my current project and work.&lt;/p&gt;

&lt;p&gt;If you are not familiar with the &lt;code&gt;micro frontends&lt;/code&gt; concept and architectures I suggest you take a look at these amazing articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://microfrontends.com" rel="noopener noreferrer"&gt;https://microfrontends.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://micro-frontends.org" rel="noopener noreferrer"&gt;https://micro-frontends.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/articles/micro-frontends.html" rel="noopener noreferrer"&gt;https://martinfowler.com/articles/micro-frontends.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are several reasons for choosing a micro frontend architecture, maybe your app has grown too much, or new teams are coding on the same repo/codebase, but one of the most common use cases is the decoupled logic of certain domain of an App.&lt;/p&gt;

&lt;p&gt;Following this logic, &lt;em&gt;good architecture is one in which micro frontends are decoupled and do not need to frequently communicate&lt;/em&gt; but there are some things that micro frontends might share or communicate like functions, components, some logic, or state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fv1598440578%2Fpackages.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fv1598440578%2Fpackages.png" alt="Draw of a package"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For functions, components and common logics could be placed on a third package and imported on each app.&lt;/p&gt;

&lt;p&gt;And for creating a package there are several approaches I won't dive deep into it, but I'll leave you some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.tsmean.com/articles/how-to-write-a-typescript-library/" rel="noopener noreferrer"&gt;Creating a simple typescript library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.harveydelaney.com/creating-your-own-react-component-library/" rel="noopener noreferrer"&gt;Creating a react component library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://claritydev.net/blog/building-component-library-with-docz-and-lerna/" rel="noopener noreferrer"&gt;Creating a component library with Lerna&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tsdx.io/" rel="noopener noreferrer"&gt;Using a Zero-config CLI for TypeScript package development (TSDX)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sharing state
&lt;/h3&gt;

&lt;p&gt;But what about a shared state? Why would someone need to share state between multiple apps?&lt;/p&gt;

&lt;p&gt;Let's use a real-world example, imagine this e-commerce:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fc_scale%2Cw_800%2Fv1590442756%2Fecommerce_1_svqcdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fc_scale%2Cw_800%2Fv1590442756%2Fecommerce_1_svqcdc.png" alt="Ecommerce wireframe with the main app, cart, item details, advertising, and suggestion microfrontends"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each square represents a micro frontend with a specific domain or functionality and could be using any framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fc_scale%2Cw_800%2Fv1590442758%2Ffull_ljpnls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fc_scale%2Cw_800%2Fv1590442758%2Ffull_ljpnls.png" alt="Ecommerce wireframe with two micro frontends pointing an arrow to the cart microfrontend"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding some content we notice some parts of the app that might need to share some data or state like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both item detail and suggested items might need to communicate and inform the cart when an item has been added&lt;/li&gt;
&lt;li&gt;The suggested items could use the current items in the cart to suggest another item based on some complex algorithms&lt;/li&gt;
&lt;li&gt;Item detail could show a message when the current item is already on the cart&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;If two micro frontends are frequently passing state between each other, consider merging them. The disadvantages of micro frontends are enhanced when your micro frontends are not isolated modules.&lt;/em&gt; this quote from &lt;a href="https://single-spa.js.org/docs/recommended-setup#ui-state" rel="noopener noreferrer"&gt;single-spa&lt;/a&gt; docs it's awesome, maybe the suggested items could be merged with item detail but what if they need to be indifferent apps?&lt;/p&gt;

&lt;p&gt;Well for those use cases I have tried 5 different modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Web Workers&lt;/li&gt;
&lt;li&gt;Props and callbacks&lt;/li&gt;
&lt;li&gt;Custom Events&lt;/li&gt;
&lt;li&gt;Pub Sub library(windowed-observable)&lt;/li&gt;
&lt;li&gt;Custom implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Comparison table&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ 1st-class, built-in, and simple&lt;/li&gt;
&lt;li&gt;💛 Good but could be better&lt;/li&gt;
&lt;li&gt;🔶 Tricky and easy to mess up&lt;/li&gt;
&lt;li&gt;🛑 Complex and difficult&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Web workers&lt;/th&gt;
&lt;th&gt;Props and callbacks&lt;/th&gt;
&lt;th&gt;Custom Events&lt;/th&gt;
&lt;th&gt;windowed-observable&lt;/th&gt;
&lt;th&gt;Custom implementation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;🛑&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Api&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;td&gt;💛&lt;/td&gt;
&lt;td&gt;💛&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Framework Agnostic&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customizable&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;🔶&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Web Workers &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I have created an example to illustrate a simple communication between two micro frontends with a dummy web worker using &lt;a href="https://github.com/developit/workerize-loader" rel="noopener noreferrer"&gt;&lt;code&gt;workerize-loader&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/matheusmr13/create-micro-react-app" rel="noopener noreferrer"&gt;&lt;code&gt;create-micro-react-app&lt;/code&gt;&lt;/a&gt; also known as &lt;code&gt;crma&lt;/code&gt; to setup the react micro frontends.&lt;/p&gt;

&lt;p&gt;This example is a &lt;a href="https://en.wikipedia.org/wiki/Monorepo" rel="noopener noreferrer"&gt;&lt;code&gt;monorepo&lt;/code&gt;&lt;/a&gt; with 2 micro frontends, 1 container app, and a shared library exposing the worker.&lt;/p&gt;

&lt;h4&gt;
  
  
  Worker 📦
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;said&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;said&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;said&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// This postMessage communicates with everyone listening to this worker&lt;/span&gt;
  &lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Container app
&lt;/h4&gt;

&lt;p&gt;The container app is sharing the custom &lt;code&gt;worky&lt;/code&gt; web worker.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;worky&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;worky&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;worky&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;worky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You should be thinking 🤔&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But why don't you import this &lt;code&gt;worky&lt;/code&gt; on every micro frontend?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When importing a library from the node_modules and using it in different apps every &lt;code&gt;worker.js&lt;/code&gt; will have a different hash after bundled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fv1598454411%2Fworkers.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdaiqkausy%2Fimage%2Fupload%2Fv1598454411%2Fworkers.png" alt="worker debug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So each app will have a different worker since they're not the same, I'm sharing the same instance using the window but there are different approaches.&lt;/p&gt;

&lt;h4&gt;
  
  
  Microfrontend 1️⃣
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;worky&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;worky&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;worky&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"MF"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Microfrontend 1️⃣&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;New messages will be displayed below 👇&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"MF__messages"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Microfrontend 2️⃣
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;worky&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;worky&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"MF"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Microfrontend 2️⃣&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;⌨️ Use this form to communicate with the other microfrontend&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"something"&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Type something in here"&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Communicate!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Pros ✅
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;According to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API" rel="noopener noreferrer"&gt;MDN&lt;/a&gt; &lt;em&gt;The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Cons ❌
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Complex setup&lt;/li&gt;
&lt;li&gt;Verbose API&lt;/li&gt;
&lt;li&gt;Difficult to share the same worker between multiple micro frontends without using a window&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Props and callbacks &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;When using react components you could always &lt;a href="https://reactjs.org/docs/lifting-state-up.html" rel="noopener noreferrer"&gt;lift the state&lt;/a&gt; using props and callbacks, and this is an awesome approach to share small interactions between micro frontends.&lt;/p&gt;

&lt;p&gt;I have created an example to illustrate a simple communication between two micro frontends using &lt;a href="https://github.com/matheusmr13/create-micro-react-app" rel="noopener noreferrer"&gt;&lt;code&gt;crma&lt;/code&gt;&lt;/a&gt; to set up the react micro frontends.&lt;/p&gt;

&lt;p&gt;This example is a &lt;a href="https://en.wikipedia.org/wiki/Monorepo" rel="noopener noreferrer"&gt;&lt;code&gt;monorepo&lt;/code&gt;&lt;/a&gt; with 2 micro frontends and one container app.&lt;/p&gt;
&lt;h4&gt;
  
  
  Container app
&lt;/h4&gt;

&lt;p&gt;I have lifted up the state to the container app and passed &lt;code&gt;messages&lt;/code&gt; as a prop and &lt;code&gt;handleNewMessage&lt;/code&gt; as a callback.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;microfrontends&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App__header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;⚔️ Cross microfrontend communication 📦&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Workerized example&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App__content"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App__content-container"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;microfrontends&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;microfrontend&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Microfrontend&lt;/span&gt;
                &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;microfrontend&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;microfrontend&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;microfrontends&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;microfrontend&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;customProps&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="na"&gt;onNewMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Microfrontend 1️⃣
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"MF"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Microfrontend 1️⃣&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;New messages will be displayed below 👇&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"MF__messages"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Microfrontend 2️⃣
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onNewMessage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;onNewMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Pros ✅
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simple api&lt;/li&gt;
&lt;li&gt;Simple setup&lt;/li&gt;
&lt;li&gt;Customizable&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Cons ❌
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Difficult to set up when there are multiple frameworks(Vue, angular, react, svelte)&lt;/li&gt;
&lt;li&gt;Whenever a property changes the whole micro frontend will be rerendered&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Custom Events &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Using Synthetic events is one of the most common ways to communicate using &lt;code&gt;eventListeners&lt;/code&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent" rel="noopener noreferrer"&gt;&lt;code&gt;CustomEvent&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have created an example to illustrate a simple communication between two micro frontends, this example is a &lt;a href="https://en.wikipedia.org/wiki/Monorepo" rel="noopener noreferrer"&gt;&lt;code&gt;monorepo&lt;/code&gt;&lt;/a&gt; with 2 micro frontends and 1 container app using &lt;a href="https://github.com/matheusmr13/create-micro-react-app" rel="noopener noreferrer"&gt;&lt;code&gt;crma&lt;/code&gt;&lt;/a&gt; to set up the react micro frontends.&lt;/p&gt;
&lt;h4&gt;
  
  
  Microfrontend 1️⃣
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Microfrontend 2️⃣
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onNewMessage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;customEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Pros ✅
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simple Setup&lt;/li&gt;
&lt;li&gt;Customizable&lt;/li&gt;
&lt;li&gt;Framework agnostic&lt;/li&gt;
&lt;li&gt;Micro frontends don’t need to know their parents&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Cons ❌
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Verbose custom events api&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Windowed observable &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In this new era of "micro" services, apps, and frontends there is one thing in common, distributed systems.&lt;br&gt;
And looking at the microservices environment a pretty much popular communication mode is pub/subs queues just like the AWS SQS and SNS services.&lt;br&gt;
Since every micro frontend and the container are at the &lt;code&gt;window&lt;/code&gt;, I decided using the &lt;code&gt;window&lt;/code&gt; to hold a global communication using a pub/sub implementation, so I created this library mixing two concerns pub/sub-queues and Observables, called &lt;a href="https://github.com/luistak/windowed-observable" rel="noopener noreferrer"&gt;&lt;code&gt;windowed-observable&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Exposing an Observable attached to a topic to publish, retrieve, and listen to new events on its topic.&lt;/p&gt;

&lt;p&gt;Common usage&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;windowed-observable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Define a specific context namespace&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart-items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Add an observer subscribing to new events on this observable&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Unsubscribing&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="c1"&gt;// On the publisher part of the app&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart-items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mouse Gamer XyZ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this library there are more features like retrieving the latest event published, getting a list with every event, clearing every event, and more!&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;windowed-observable&lt;/code&gt; on the same app example:&lt;/p&gt;

&lt;h4&gt;
  
  
  Microfrontend 1️⃣
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;windowed-observable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;messages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleNewMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;currentMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;handleNewMessage&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Microfrontend 2️⃣
&lt;/h4&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;windowed-observable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;messages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;something&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Feel free to take a look and also use it ❤️&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/luistak/windowed-observable" rel="noopener noreferrer"&gt;windowed-observable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/luistak/windowed-observable/tree/master/packages/react" rel="noopener noreferrer"&gt;react-windowed-observable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Pros ✅
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simple api&lt;/li&gt;
&lt;li&gt;Simple setup&lt;/li&gt;
&lt;li&gt;Pretty much customizable&lt;/li&gt;
&lt;li&gt;Namespace events isolation&lt;/li&gt;
&lt;li&gt;Extra features to retrieve dispatched events&lt;/li&gt;
&lt;li&gt;Open source ❤️&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Cons ❌
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/florianrappl/comment/16kgj"&gt;This library depends on the window so anyone can change its implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Custom implementation &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After all of these examples you could also merge some of them and create your custom implementation, using &lt;strong&gt;your abstractions&lt;/strong&gt; encapsulating your app needs, but these options could be tricky and easy to mess up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is no perfect or best solution, my suggestion is to &lt;a href="https://kentcdodds.com/blog/aha-programming/" rel="noopener noreferrer"&gt;avoid hasty abstractions&lt;/a&gt; and tries to use the simplest solution like props and callbacks if it does not suit to your needs try the other one until it feels good!&lt;/p&gt;

&lt;p&gt;You can dive deep in those examples in &lt;a href="https://github.com/luistak/cross-mfe-communication" rel="noopener noreferrer"&gt;this repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Comment below which one you prefer and why 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>microfrontends</category>
      <category>micro</category>
    </item>
  </channel>
</rss>
