Why many teams are better off with monoliths than with micro front ends

The hype surrounding micro front ends is cooling off. Monoliths can be a more suitable software architecture, especially for small web development teams.

listen Print view
Hindukusch

(Image: Daniel Prudek / Shutterstock)

13 min. read
By
  • Nicolai Wolko
Contents

Software architecture knows fashions and counter-movements. Cutting frontends into tiny independent parts has been considered modern in recent years: Micro front ends and microservices. Today it is clear that the approach remains valuable. But only where it actually reflects the organizational reality. For many small to medium-sized teams, a modular monolith is often the more robust starting architecture.

Nicolai Wolko
Nicolai Wolko

Nicolai Wolko ist Softwarearchitekt, Consultant und Mitgründer der WBK Consulting AG. Er unterstützt Unternehmen bei komplexen Web- und Cloudprojekten und wirkt als Sparringspartner sowie Gutachter für CTOs. Fachbeiträge zur modernen Softwarearchitektur veröffentlicht er regelmäßig in Fachmedien und auf seinem Blog.

The international State of Frontend survey conducted by The Software House shows a clear movement: in 2022, 75.4 percent of respondents said they used micro frontends. In 2024, it was only 23.6 percent. This sounds dramatic at first glance, but it is not the death of the idea. The decline shows that many teams no longer regard micro front ends as a standard solution but use them selectively where organizational or architectural reasons justify it. At the same time, the popularity of module federation is increasing, and not just for micro-frontends: in 2024, 51.8% reported using it, often in monolithic applications, to update parts independently. This supports the thesis of consolidation into fewer deployment units while retaining a modular structure.

It is worth noting that AI also favors microservices: if you ask ChatGPT about architecture patterns without context, it almost always recommends microservices and often micro front-ends. This is not an indication of universal correctness but of the hype bias in the training data. Without technical classification, it remains a statement of probability and is no substitute for the analysis of an experienced architect.

Micro-frontends originated as an analogy to microservices and are enjoying great popularity for good reason. The idea is to split cumbersome SPAs or web portals into small, autonomous apps. Each team can develop its own piece with its favorite framework and deploy it independently. This reduces the coordination effort, avoids monolithic rebuilds, and allows parts of the front end to be loaded asynchronously.

In practice, however, this freedom often leads to new problems: multiple frameworks or UI libraries increase the download size and extend the time to interactive, global stores or shells create the infamous hidden monolith or distributed monolith where micro apps continue to share the same state, and additional deployments create overhead for CI/CD, feature flags, and versioning.

Micro frontends are suitable when truly independent teams and heterogeneous stacks come together, for example, at tech giants such as Amazon or Spotify. In many projects, however, additional orchestration creates more issues than it solves and quickly leads to complex builds and longer loading times. Especially for smaller teams and clearly defined products, the effort involved exceeds the benefits, and the hoped-for decoupling does not materialize. The result is often a distributed monolith with numerous sub-projects that can only live together. This is a fatal development, as the distributed monolith often combines the worst characteristics of both worlds.

The debate about monoliths and microservices often suffers from a lack of clarity. A post on the Dev Details blog clearly explains that the classification does not depend on the number of repositories, containers, or teams:

  • A monolith is created when several parts are so tightly coupled that they can only be deployed together.
  • Microservices, on the other hand, are characterized by loose coupling and high cohesion. They can share data and resources with other services as long as each component retains its responsibility.
  • Serverless only means that infrastructure management is abstracted. It is not a synonym for Function as a Service. The key point is that teams do not have to worry about servers and only pay for actual usage.

This perspective helps to demystify buzzwords. You can mix monolithic, microservices-based, or serverless architectures—the decisive factor is how strongly the components depend on each other. If several services always have to be deployed together, the result is effectively another "distributed monolith."

The team behind Amazon Prime Video is often cited, as already reported on heise. In 2023, it switched the audio/video monitoring component from a step-function-driven distributed design to a monolithic process design, which led to over 90 percent lower costs and higher scalability for this component.

This is not a move away from microservices across the product but a clear context-specific optimization: fewer network hops, elimination of S3 caching, and less orchestration overhead.

An excellent example of how architecture should not follow a label, but in this case the load profile and coupling. Microservices and serverless are tools that work great for the right class of problems, but otherwise a more tightly coupled design is cheaper and easier to operate.

Practical experience confirms this view: Ken Kantzer, VP Engineering at FiscalNote and founder of the security and architecture consultancy PKC Security, has identified recurring patterns in over twenty code audits of start-ups. His findings: the most successful companies deliberately kept their architecture simple. Teams that consistently worked according to the “keep it simple” principle went on to dominate their markets.

In contrast, many companies that plunged into complex architecture experiments early on disappeared. Kantzer considers the premature switch to microservices, highly distributed systems, and messaging-heavy designs to be a self-inflicted trap that maneuvers teams into unnecessary operational and development issues. His audits showed that such systems blocked much of the developer's time with queue errors, version incompatibilities, and network latencies, while actual product development stalled.

The lesson: complexity is not an investment in future viability if it gets ahead of the context—it is a cost factor that can jeopardize market success.

The modular monolith, or modulith, combines the advantages of monoliths and microservices: the application is divided into clearly delineated modules that can be developed, tested, and versioned independently internally but are deployed together. Thoughtworks describes it as the “best of both worlds”: there are fewer moving parts, simple deployments, and lower infrastructure costs, while a clear division into modules is still possible. The common deployment unit eliminates the need for gateways, service discovery, and distributed logging. This improves performance, as modules communicate via function calls instead of the network, and the system does not immediately fragment if a module fails. At the same time, clear team boundaries and domains can be defined so that developers can spin off a module relatively easily at a later date.

Videos by heise

The architecture experts behind the Ptidej tool suite provide a practical decision-making aid in the form of a table. Microservices offer advantages when autonomous teams with their release cycles work on different parts of a large system, when individual components scale very differently, or when different technologies are required. A monolith, on the other hand, is sufficient if the team is manageable, the domain is clearly defined, and the scaling requirements are homogeneous. It is important that the system remain modular so that it can be broken down into microservices later if required.

The modular monolith therefore offers a pragmatic middle ground: it divides an application into clearly defined modules but deploys them together. In the Python/Django environment, this principle has been common practice for years (“apps” as module boundaries), even if it is not called Modulith there.

Thoughtworks recommends starting with such a monolith and only outsourcing individual modules after a thorough understanding of the business processes. The advantages are clear: simple deployments, good performance, lower operating expenses, and less latency.

Modern monorepo tools reduce the friction of larger code bases: Nx, for example, offers computation caching (local and remote) and “affected” mechanics so that when changes are made, only the affected projects are built and tested. This drastically reduces build and CI times and makes a repo with many modules practicable.

It is interesting to note that Nx explicitly documents that micro-frontends are recommended above all when independent deployment is really necessary. Otherwise, the same build effects can increasingly be achieved without a micro-frontend architecture (e.g., module federation only for build acceleration).

Pragmatic guidelines can be derived from data, practical reports, and tool trends:

  1. For most small to medium-sized teams, a modular monolith is the fastest route to features and feedback. It reduces costs, minimizes operational risks, and remains evaluable.
  2. If components always have to be deployed together, the application is monolithic—regardless of how many containers or repos it is distributed across. Conversely, microservices only make sense when deployments are truly independent.
  3. Distributed systems come with operating costs: observability, versioning, backward compatibility, network latency, and CAP trade-offs (trade-offs between consistency, availability, and partition tolerance). Those who do not have or do not need this maturity lose time and focus on the product. This is exactly what code audits from start-up practice show.
  4. What makes sense in a corporation with dozens of teams is often overkill for a team of ten people. Architecture follows team structure and business process, not blog hype. The article on Heise carefully categorized this using the prime video example (keyword Modulith).
  5. If individual modules become bottlenecks (deviating release rhythm, strongly deviating load, different team), they can be separated cleanly. The complexity remains manageable without premature fragmentation.

Don't miss any news – follow us on Facebook, LinkedIn or Mastodon.

This article was originally published in German. It was translated with technical assistance and editorially reviewed before publication.