- **Epistemic status:** #evergreen ![[micro-frontend.drawio.svg]] Micro-frontend architecture is a [[Modularity]] approach that separates views into services separately built with their own framework and technologies. When deployed, the application consumes server-side rendered [[HTML (HyperText Markup Language)]], [[CSS Cascade Layers]], and [[JavaScript]] via CDN. [[DDD - Domain Driven Design]] is utilized in conjunction to this approach to define how to separate each micro-frontend and how to handle communication with a microservice. Each micro-frontend should be able to work on its own without relying on any other dependency. Let's review the benefits and challenges of this approach. ## Benefits ### Development flexibility Teams have the freedom to decide their preferred technologies for a micro-frontend without affecting other teams, improving collaboration within them. The benefit augmented further when dealing with teams in multiple timezones, since each team can be focused on one or multiple services instead of working on one monolith application. ### Decoupled services By separating views into their own [[Bounded Context]] they follow [[Easier to Change (ETC) principle]] where faults in the micro-frontend do not impact the other parts. This isolation makes development, testing, and deployment a smoother process. ### Easier maintenance Maintenance becomes an easier task since it won't have a ripple effect across the application. If need be, refactoring the full micro-frontend is a faster and easier task, avoiding technology lock-in. ### Faster iterations Teams are able to make small improvements in a micro-frontend and deliver them separately, utilizing delivery pipelines to ensure a good evolution of the system overtime. ### Reuse services Many services are common in an application such as payment processing, user log in, account management, etc. Using this approach, you can quickly adapt a micro-frontend to an application, saving time instead of reinventing the wheel. ## Challenges ### Increased complexity Developing a good management strategy is required as the number of micro-frontends increase because there will be more teams, tools, codebases making the ecosystem more complex. The amount of onboarding time increases as well since engineers would need to be trained on how to work on various systems and when moving teams might encounter different technologies. To decrease the complexity, you can [[Define Team Principles]] and a [[Ubiquitous Language]] for all teams. This can serve as guide posts improving communication and collaboration when they need to interact with each other. ### Inconsistent user experience The complexity described previously contributes to an increased danger of delivering an inconsistent user experience, since each team might be using their own tools or have different working styles. Due to the nature of [[Cascading Style Sheets (CSS)]] where styles inserted from a micro-frontend can affect the styles on the container application, even when using Sass or [[Cascading Style Sheets (CSS)]] modules. You need to ensure that developers can create styles that don't impact other micro-frontends and container application. You can [[Define a naming convention using Atomic Design and BEM]] to reduce clashing styles and implement the shadow DOM on the micro-frontend to isolate styles for each platform. A [[Design Language System]] can create a more consistent user experience across applications. This needs to be accompanied by a shared UI component library that is technology-agnostic, reducing the need to duplicate code (See [[Don't repeat yourself (DRY) principle]]). The library will serve as a [[Ubiquitous Language]] between designers and developers. When performing [[Component-based Development]] you can create dumb components that don't have any domain and business logic to avoid coupling across applications, increasing the difficulty of making a change (See [[Easier to Change (ETC) principle]]). Lastly, have a team or an individual be a custodian responsible for ensuring the quality, consistency, and validity of the contributions made by others since it is best to allow anybody to contribute to it. ### Larger payload Another risk due to the complexity described previously is that with autonomous teams working on different codebases, there will be duplicated code, impacting the performance of the application. This can be either code developed internally or externally as dependencies, for example NPM dependencies like React. ### Managing communication between applications The product still needs to look like a seamless experience and since each micro-frontend is decoupled there needs to be efficient communication channels between each application. A good practice is to have them communicate as little as possible and to send events instead of using any shared state. The same goes for sharing a database across microservices. Each microservice needs [[Modularity]] by applying [[DDD - Domain Driven Design]] enforcing that it does not need other applications to run successfully. ## Implementing micro-frontend architecture There are many approaches that can be considered micro-frontend due to the loose definition described above. Each method has its pros and cons. You can pick whichever approach or combination of approaches that fits your organization better. ### Server-side composition The server receives a call from the client to render and compose the different micro-frontends, serving it as one application to the end user. With this approach, the content can be cached on the server to deliver the application faster, reducing load times for the user. The rest of the application can use lazy-loading while the core offerings are served. You can even include a server per micro-frontend to allow other applications to request the page as well. ### Built-time integration The micro-frontend is published as a package that can be consumed by the container application, making it easy to bundle all the code together. Another benefit that common dependencies shared can be specified, reducing the bundle size. The downside of this approach is that every time an update rolls out you will need to update the container application, bundle the new code, and deploy it. The releases of each micro-frontend get tied to other applications release processes, making it difficult for teams to be autonomous. ### Run-time integration via iframes An approach that has been around for years. iframes have isolated functionality and styling. It is easy to implement and deploy. The downside is that this isolation can lead to issues when applications aren't split properly, depending on other parts to function. Responsive design becomes difficult to implement. Preserving routing history is difficult to keep. They can also present challenges with accessibility. ### Run-time integration via JavaScript One of the most popular and flexible approaches where each micro-frontend is included into the page using a `<script>` tag. When it loads, it exposes a global function as the entry point. The container application calls the function rendering the micro-frontend where it is needed. ### Run-time integration via Web Components Similar to the previous integration, instead of a global function, it defines a custom HTML element hosting the micro-frontend that the container application can render. ## Examples ### Model store ![[Pasted image 20220404084138.png]] - [Site](https://micro-frontends.org/1-composition-client-only/) - [Repository](https://github.com/neuland/micro-frontends/tree/master/1-composition-client-only) ### Feed me ![[Pasted image 20220404084250.png]] - [Site](https://demo.microfrontends.com/) - [Repository](https://github.com/micro-frontends-demo) --- ## References - “🍽 Feed Me.” Accessed March 28, 2022. <https://demo.microfrontends.com/>. - “Micro Frontends.” Accessed March 28, 2022. <https://microfrontends.com/>. - Micro Frontends. “Micro Frontends - Extending the Microservice Idea to Frontend Development.” Accessed April 4, 2022. <https://micro-frontends.org/>. - Insights on Latest Technologies - Simform Blog. “Micro-Frontend Architecture: Principles, Implementations and Challenges,” June 10, 2021. <https://www.simform.com/blog/micro-frontend-architecture/>. - GitHub. “Micro-Frontends-Demo.” Accessed March 28, 2022. <https://github.com/micro-frontends-demo>. - Stack Overflow. “Reactjs - Micro-Frontends, Web Components, and Sharing Libraries.” Accessed April 5, 2022. <https://stackoverflow.com/questions/56561807/micro-frontends-web-components-and-sharing-libraries>. - “WebAIM: Creating Accessible Frames and Iframes.” Accessed April 4, 2022. <https://webaim.org/techniques/frames/>.