Micro Frontends – The Evolution of Microservice Idea to Frontend Development

Many companies revere distributed systems as a one-size-fits-all approach, which optimally solves any software issue, but does it?

This article explores architecture options from various monolith types and transition options to micro frontends in action: their characteristics, merits and demerits, indications, and nuances between micro frontends in monorepos and multirepos. Be sure to make informed decisions in your frontend architecture journey after perusing this go-to article.

Should any of these questions bother you, keep on reading:
  • What is micro frontend architecture?
  • How to find out if I need micro frontends?
  • What is the difference between monoliths, integrated apps and micro frontends?
  • How are present-day monoliths similar to and different from distributed systems?
  • What are the risks of micro frontend architecture?
Micro Frontends – The Microservice Idea in Frontend

Micro frontends – an ultimate solution for weak software?

There is an ever-aggravating problem software is bound to face. The thing is that even the simplest software tends to expand and get more complicated as time passes, which eventually results in failures or malfunctioning. The question of how to tackle this nasty tendency remains open.

It is a given that engineers enjoy taking on challenges when it comes to solving problems, so companies have now come to acknowledge the limitations of the monolithic approach and set off to fix scaling-related issues. Strategies like distributed or micro frontend architecture do address certain problems, nevertheless, some challenges come with it as well.

It should be borne in mind that straightforward adherence to micro frontend frameworks – for they can solve the problem of software complexity – is a poorly made decision, and here is why. Leveraging a particular solution is barely about the ease of implementation, but rather about actual problem-solving.

An illustration would be putting micro frontends into action: it seems promising, but working with distributed systems is exceptionally challenging. The difficulty persists further on in the process: halfway through implementation, there arise doubts about whether the selected measure should help the original problem. The danger lies in distributing problems across layers, emphasizing the need to solve issues without introducing more complexities. An additional issue occurs when instead of thoroughly examining available choices, we focus solely on micro frontend structure.

What we can now do to prevent the pitfalls that await all those eager to leverage the obvious options is: to identify and define a problem precisely, evaluate if micro frontends are the optimal solution, explore alternative options before making a decision, and remember that the best outcome is the one not creating more problems or complications. We will further look into these matters in more detail.

Misleading micro frontend indications

Encounters with distinct challenges that manifest as symptoms can trigger many to consider distributed architecture. These issues arise in various situations, each demanding a unique remedy. Let us get a closer look at the most common ones.

Symptom: application instability

  • Applications become fragile (Butterfly Effect)
    As one of the primary symptoms prompting the consideration of micro frontends, app instability is diagnosed whenever a minor change in one part of the system entails significant consequences and repercussions across the entire app, resembling the cascading effects of the Butterfly Effect.
  • Lack of confidence when shipping new versions
    The lack of confidence in shipping new features stems from the fear that any modification might break the application. Originating in the app’s fragility, the odds of inadvertently causing issues make engineers hesitant to implement changes or deploy new features.
  • Lack of failure isolation
    The major factor contributing to the lack of confidence is the absence of failure isolation, whereby amendments causing a problem can bring down the application. This interconnectedness amplifies the impact of any emergent issue, further emphasizing the critical symptom of fragility.

Symptom: exponential growth

  • Increased number of lines of code and developers
  • CI/CD Pipelines and deployments become slow
  • Difficulties scaling the technology and the organisation

Despite the initial promising scenario that growth brings along for business, exponential growth is a problem – balancing technological advancements with organizational needs becomes a challenging aspect in this scenario. As the influx of new developers leads to increased application and feature development, several challenges emerge: slow CI/CD pipelines and prolonged deployment times pose difficulties in managing infrastructure and overseeing people and the organization as a whole.

Symptom: organisational issues

  • Lack of team ownership
  • Developers require a lot of contexts before they can make changes
  • Steep learning curves and overwhelming codebases

When experiencing a lack of team ownership, individuals struggle to identify what they are meant to maintain or own within a large application. The overwhelming nature of the codebase requires a long while to go through, resulting in a prolonged and steep learning curve for newbie developers.

One problem – diverse solutions

Straightforward and auspicious as distributed architecture may seem, focusing solely on it leads to overlooking other potential and sometimes more suitable solutions to the problem. The rush to transition from a monolith to a micro frontend architecture without thoroughly exploring alternative approaches can bring about unfavorable aftermath. Once again, it is crucial to assess whether micro frontends are the optimal solution and consider other alternatives before making such a significant shift. Such options that can treat architecture issues are going to be discussed later on in the text.

Monoliths

The diagram you can see below represents the so-called “Distributed and Decoupled Spectrum,” the process of decoupling an application from a monolith to distributed architecture is a crucial journey. The journey across the spectrum starts with a monolith at one end and consists in progressively applying various techniques to get to the other extreme of the spectrum – microservices. The initial point and the ultimate solution are what everyone following this path is going to have in common whereas distinct steps and choices are going to vary. Let us delve into each step and assess which option might be a suitable fit for implementation in different companies.

Independently deployable and decoupled application structure

The starting stage, the monolith, tends to be perceived as a legacy and not trendy. However, monoliths are essential for a few reasons. Firstly, most applications start as monoliths: they offer simplicity with a single deployment unit. Secondly, monoliths are functional since they have the capacity to scale to two million users. Although challenges exist, in certain scenarios, monoliths remain a viable option.

We will further explore not only the nuances of different monolith types: the full-stack monolith, followed by an examination of the front-end monolith, as well as a novel type known as the meta-framework but also look into the transition options, such as the modular monoliths and integrated applications. At the end, you will also find a comprehensive answer to the question “What are micro frontends?” and weigh up the micro frontend pros and cons, depending on your particular case.

Full-stack monolith

To kick off, this is the traditional model that used to be the standard coding approach. In a full-stack monolith, the backend and frontend reside together, sharing the same codebase, connecting to a single database or data store, and functioning as a unified deployment unit. Before the era of microservices and the segmentation of the frontend into distinct single-page applications, the full-stack monolith prevailed.

Pros of full-stack monolith

  • Ease in the early stages
    A monolith simplifies development in the initial phases and is especially suitable for small projects.
  • Expedited development:
    The structure also speeds up the development process, being particularly beneficial for small teams working collaboratively.
  • Consolidated codebase
    Monolithic architecture facilitates the location and modification of elements within a consolidated structure.

Cons of full-stack monolith

  • Scaling issues
    As the project is bound to grow, so are the challenges in scaling a full-stack monolith app, both technologically and technically.
  • Lack of framework flexibility:
    Monoliths pose inherent limits in choosing different frameworks for the backend and frontend.
  • Increased coupling
    Increased interdependence in the codebase may complicate modifications.

Examples of full-stack monoliths include Stack Overflow, still running on-premises with a monolithic architecture that scales effectively. GitHub, once a full-stack monolith, is transitioning away. Microservices, introduced alongside the API boom, marked a shift, empowering front-end developers to work independently as systems separated.

The front-end monolith

Stepping away from full-stack monoliths, our first destination is the front-end monoliths, where the backend is separated, and communication occurs through APIs. This transition aligns with the rise of single-page applications and API communication.

Pros of the front-end monolith

  • Independence of the backend
    The backend becomes independent, avoiding the concentration of too many components in one place.
  • Flexibility in using modern JavaScript frameworks
    With communication through APIs, there is no restriction on using specific backend or frontend frameworks, providing flexibility.
  • Benefits of single-page applications (SPA)
    the user experience advantages of single-page applications are quite enjoyable, enhancing both user and developer experiences.

Cons of the front-end monolith

  • Monolithic nature
    despite being focused on the frontend, it remains a monolith, bringing forth similar challenges encountered with full-stack monoliths. The difficulty of introducing changes increases with the bulky size of the application and the number of developers involved.

Modern front-end monoliths, including popular libraries like React, Vue, and Angular, often communicate through APIs and are typically hosted in a single repository. Many companies adopting microservices leverage front-end monoliths to implement the view layer of their applications.

Meta-frameworks

With the emergence of the “new front-end monolith” or, in other words, the meta frameworks, we witness the evolution of sophisticated frameworks rooted in JavaScript. Interestingly, this evolution introduces a backward trend, allowing connections to databases within the monolith.

Meta-frameworks, also known as cross-platform frameworks, enable developers to create applications that can run on multiple platforms with a single codebase. Some well-known apps built using these frameworks include: Facebook, Instagram, Airbnb, UberEats. These examples showcase how well-known companies have successfully used meta-frameworks to build cross-platform applications, saving development time and resources while delivering consistent user experiences across various devices and platforms.

Pros of meta-frameworks

  • Benefits of single-page apps
    They evolve from the single-page application paradigm, integrating advanced functionalities.
  • Implementation diversity
    Meta frameworks bring back features like routing, server-side rendering, and authentication, providing a versatile range of implementation options.
  • Flexibility and modularity
    Offering a high degree of flexibility and modularity, these frameworks allow choosing between separate microservices or integrating databases within the monolith.
  • Modern tooling
    New Front-End Monolith utilizes new, faster tooling and JavaScript Frameworks, enhancing the overall developer experience.

Cons of meta-frameworks

  • Monolith-associated drawbacks
    They retain the inherent challenges of a monolithic structure, dealing with issues that arise when multiple contributors work on the same codebase.
  • Scaling issues
    While offering improved modularity and development experience, the fundamental challenge lies in scaling the application. Monoliths, and meta-frameworks are no exception, face issues as the scale of the application increases.

Modular monolith

The tendency of full-stack monoliths to burden the app prompted many explorations into alternative solutions before arriving at micro frontends. One example of this is the modular monolith, a concept that emerged as an answer to the challenges of modularity, scaling, and collaboration. Basically, the modular monolith seeks to introduce a degree of separation and modularity within the code, employing domain-driven design principles to organize elements logically. Despite this attempt at modularity, most implementations still retain a single deployment unit, entailing intricate tooling to stitch the modules together and deploy them collectively.

Monolith vs modular monolith

Pros of modular monolith

  • Increased scalability
    Due to modular design principles, this approach to architecture offers improved scalability compared to traditional full-stack monoliths.
  • Low complexity
    Modular monoliths try to balance modularity with being less complex than a fully distributed architecture.
  • Better code organization
    Leveraging domain-driven design principles and enforcing better structural organization allow modular monoliths to boast of enhanced code organization.
  • Enforced boundaries
    Architecture sets certain boundaries within the monolith, thus ensuring a degree of separation between modules.

Cons of modular monolith

  • Single deployment unit
    As a monolith, this approach still keeps the limitation of being a single deployment unit, hindering the independent deployment of modules.
  • Dependencies among modules
    While introducing modularity, modular monolith structures cannot claim complete independence since the modules may still exhibit dependencies on one another.
  • Large codebase
    Despite efforts to modularize, the overall codebase remains a substantial challenge for developers to browse through.

The modular monolith approach emerged as an attempt to bypass the complexities associated with a full transition to microservices. It came in handy as many companies, hesitant to fully embrace microservices, opted for a compromise with the implementation of a modular monolith.

The Shopify modular monolith stands out as a prominent example. The company opted for a modular Ruby on Rails monolith instead of pursuing microservices, citing reasons for achieving faster development and deployment. While the industry evolves rapidly, the insights from their decision-making process provide valuable perspectives on the advantages of a modular monolith.

Integrated applications

Truth be told, it is quite difficult to draw a clear-cut line between modular monoliths and integrated apps, though they are considered distinct. The latter finds itself in the middle ground between monoliths and fully distributed architectures. Being ambiguous enough, the concept of integrated applications is different from both micro frontend frameworks and modular monoliths, and we are going to illustrate the distinction later in the text.

One peculiar common association with integrated applications is the use of monorepos. Integrated applications typically take the form of monorepos where various sections of the application are organized and potentially deployed independently. This approach simplifies splitting applications, and many companies employ similar strategies, even if they do not explicitly label them as integrated applications.

That being said, it is important to recognize that monorepos are a tool for code organization rather than a determiner of the architectural outcome. The key lies in how the code is organized within the monorepo. Monorepos prove valuable in creating modular sections of applications that exhibit a degree of independence greater than that of a typical modular monolith. In certain cases, these modular sections can become so autonomous that minimal changes enable them to deploy as fully independent entities.

Pros of integrated applications

  • Increased independence and modularity
    Those are inherent in integrated applications as they organize app sections more autonomously within monorepos.
  • Decoupled architecture
    A more flexible and adaptable system is attributed to a level of decoupling between different sections of the application.
  • Varied deployment
    While individual modules can be updated independently, the final deployment to production involves assembling these separately deployed modules into a cohesive whole.
  • Manageable complexity
    Integrated applications, with their increased independence and modularity, contribute to a more manageable system in terms of complexity.

Cons of integrated applications

  • A single deployment unit
    Being faithful to their monolith legacy, integrated applications still limit the granularity of independent deployability.
  • Fragmented UI
    The independence of applications within the integrated structure may lead to a fragmented user interface, adversely impacting the overall user experience.

Some instances of integrated apps involve multiple monolithic instances that operate independently, each with its own URL. For instance, a Versa article detailed deploying applications from a monorepo into a unified tool, assigning separate domain URLs, like subdomains, for different functionalities such as documentation and the main application. While this approach allows potential code sharing, it introduces challenges like independence issues, communication gaps, and a suboptimal user experience due to full-page refreshes during transitions, highlighting potential maintenance concerns.

Micro frontends

Having started with the extreme of monoliths, as we approach the conclusion, we arrive at the realm of micro frontends. They represent a fully distributed architecture, which offers the benefits of independent apps, multiple deployment units, and team autonomy. Should there be any chance of attaining these advantages without adopting micro frontends, it is a sign to reconsider your architecture choices, for fully distributed architecture is meant for independent deployability.

As per the composition of individual micro frontend modules, two types of micro frontends are distinguished: build-time and runtime. The former refers to the type of composition, whereby different micro frontend modules are assembled or composed into a unified application (the shell) during the build process and then deployed as a single unit.

What is micro frontend architecture

Meanwhile, the latter allows the micro frontends to remain independent during the build process, in this way integration of these micro frontends occurs dynamically at runtime when the user accesses the app – this runtime composition is more associated with micro frontends. The reasons behind it include runtime practicality from simple single-page apps to more intricate cases like server-side rendering, organizational practices facilitation, multiple repositories for micro frontends, ensuring independence and adhering to the singular responsibility principle.

Pros of micro frontends

  • Independent development
    Multiple teams can work on their separate micro frontends without interfering with each other by using different frameworks, libraries, or technologies, without creating bottlenecks.
  • Isolation and modularity
    Modification to one micro frontend does not affect others, due to modular independent development and updates.
  • Scalability
    Micro frontend addition is no problem for this architecture, fostering seamless scalability.
  • Reuse of components
    Consistency, as well as minimized redundant development effort can be achieved with the help of the mono repository’s shared components or libraries.

Before embracing micro frontends, it is crucial to conduct a thorough evaluation of the project’s requirements and other factors like team proficiency, project scale, and long-term maintainability. While this architectural approach presents valid advantages, it also introduces potential drawbacks.

Cons of micro frontends

  • Complex configuration
    Establishing and maintaining a scalable build system may demand additional effort and resources, especially as the codebase or the number of micro frontends grows.
  • Dependency management
    Since introducing changes in one micro frontend may affect others, this kind of architecture poses an increased need for managing dependencies so as to prevent compatibility issues.
  • Technology diversity
    It is undoubtedly a benefit that tags along certain challenges in maintenance, knowledge transfer, and ensuring consistent practices across the codebase.
  • Testing challenges
    Ensuring thorough testing of elements that have been produced by different teams, can be quite demanding.

According to the architectural approach, micro frontends can be further categorized into those managed within a monorepository (monorepo) and those organized in multi repositories (multirepos). We are going to explore those two subtypes of distributed architecture in more detail in the following article subsections, including the comparison of monorepos vs multirepos.

Micro frontends with monorepos

Distributed architecture modules within monorepos encompass an architectural strategy for organizing the codebase of software projects wherein a frontend application is conceived as a set of loosely connected and independently deployable components. These components, the micro frontends, are stored and organized within a monorepository (monorepo) framework.

Within a monorepo, diverse projects or applications coexist within a unified repository, sharing essential dependencies and development tooling. Each micro frontend corresponds to a distinct feature, module, or functionality embedded within the overarching frontend app. The appeal of this approach is in the autonomy of each micro frontend, allowing them to undergo development, testing, and deployment in isolation.

Micro frontends with multirepos

On the other hand, a frontend with multirepos signifies an architectural strategy where distinct frontend projects are maintained in separate repositories, each having its own codebase, dependencies, and development tooling. In this approach, micro frontends are developed, tested, and deployed independently within their respective repositories, though they come together only conceptually as a set of frontends with multiple individual repositories.

The combination of micro frontends and multirepos offers flexibility and scalability in frontend development, proving particularly advantageous for complex projects with multiple teams contributing to the codebase, or when a project approaches a deadline and loads of parallel work is to be done promptly. While this architecture subtype offers isolation and autonomy for each micro frontend, it may introduce challenges related to consistency, code sharing, and managing dependencies across multiple repositories.

Monorepos vs multirepos

When comparing the micro frontend with a monorepository against the micro frontend with a multirepository, the essence is as follows.

Monorepos

Encourage a centralized approach, potentially fostering more consistent practices across micro frontends. So, they are better suited for projects where shared components, consistency, and centralized management are crucial since they enforce coding standards and practices across micro frontends.

Multirepos

Allow for greater autonomy and flexibility for individual micro frontend teams, and thus are more fit for projects where independence, varied technologies, and decentralized development are priorities.

Each of these two architectural approaches comes with its indications and benefits for the overall project. It is quite common that they change each other at different points in a project’s evolution. The decision between monorepos and multirepos depends on project size, team collaboration, and the desired level of independence for each frontend module among other factors, and had better be made after consulting an expert.

Yarema Yurchyshyn
Yarema Yurchyshyn Full Stack Engineer at Romexsoft | AWS Certified Solutions Architect - Associate
Share The Post