Micro Frontends — The Better Way to Modernize Legacy Applications
Picture a scenario all too familiar in software engineering: a legacy application, once cutting-edge, now a relic of yesterday’s technology. While the product remains vital to the business, its relevance is fading due to an outdated user experience and lack of extensibility. The application’s fragile state and towering technical debt have given the engineering team unrelenting anxiety. Everyone, including leadership, wants it replaced, but the undertaking seems insurmountable. It is a relentless struggle to evolve, one I have witnessed countless times in my years of consulting.
Fortunately, two distinct, yet complementary engineering paradigms can provide a path forward:
While seemingly unrelated on the surface, when paired together, these concepts forge a unique and powerful transformation strategy that can deliver a modernized product to market in a fraction of the time. Meanwhile, organizations are able to defer costs, maintain stability, and guard against uncertainty. Embraced by industry titans such as Spotify and Upwork, this winning combination of ideas promises to revolutionize how digital products evolve and thrive in a rapidly changing landscape.
The Big Bang
The often-instinctive approach to modernization, dubbed the “big bang,” involves a complete rewrite of the entire application from the ground up. A push to upgrade underlying technology can make pursuing such a strategy particularly compelling. While this may seem like the right answer and certainly sets the stage for an exciting product launch, it has proven to carry substantial drawbacks and risks:
Throughout the digital era, there have been many notable cases that underscore the potential impact of the big-bang misstep:
Strangler Fig Pattern
Undoubtedly, an agile approach would be far more favorable. This is where the Strangler Fig Pattern aligns. Coined by Martin Fowler, this term finds its metaphorical roots in the unique lifecycle of the strangler fig tree. Initially emerging as a vine, the strangler fig grows to envelop an older, more established tree, intricately weaving its way around the host until it eventually overtakes and replaces it entirely.
To put this in real terms, our objective should be to facilitate a gradual transition where the existing system and its eventual replacement are able to harmoniously coexist side-by-side for an interim period. The two infrastructures must operate concurrently in a way that is entirely invisible to the user without causing disruption or compromising functionality. Once coexistence is achieved, the outgoing system is then decommissioned in stages as its responsibilities are gradually transferred to its modern counterpart. This iterative process continues until all legacy components and services are phased out, and the original system is eliminated altogether.
When implemented effectively, the Strangler Fig Pattern significantly mitigates the risks associated with large-scale replacements. Instead of waiting for a complete system overhaul, new components are integrated and released independently as they are developed. These incremental updates can be deployed swiftly and regularly, while the rest of the application as a whole continues to function as normal. The flexibility inherent in this approach accelerates value delivery and empowers organizations to prioritize and reimplement features selectively based on budget constraints, resource availability, and other business priorities.
Breaking up the Monolith
The essence of the Strangler Fig Pattern is to incrementally build a new system around the edges of the old and replace functionality piece by piece. While this does not require a system to be fully distributed, it does require a high degree of modularity.
The first step is to identify or establish technical boundaries within the existing application, commonly referred to as “seams.” Seams act as delineation points of modularity, facilitating the subsequent decoupling and decomposition of the application into smaller, independent, and replaceable units. Creating these lines of separation is a two-dimensional puzzle, requiring both horizontal and vertical considerations:
For a monolithic backend, vertical segmentation often involves transitioning to a microservices architecture. Microservices streamline the incremental replacement of services and facilitate a smooth transition without disrupting the existing system.
For the frontend, however, decomposition is not so straightforward. Frontends tend to be tightly coupled with complex interdependencies, making it very challenging to create these seams. This is why many engineers find the Strangler Fig Pattern applicable only to backend migrations. Consequently, frontends are often left in their holistic state and replaced as one unit. Thankfully, there is an answer hidden in a design pattern most commonly associated with scalability. This is where micro frontends take center stage.
Micro Frontends
Micro Frontend architecture (or MFE for short) is a design pattern and set of principles that allows engineering teams to independently develop, test, deploy, and scale fragments of a UI as decoupled units. These units (called micro frontends) are then reassembled (usually at runtime) into one cohesive user interface.
MFE gained popularity after the explosive adoption of microservices as a way to extend that same level of modularity to the frontend. In many ways, micro frontends and microservices are mirror images of each other:
Recommended by LinkedIn
By allowing components to originate from independent deployments, and further permitting competing technologies (such as React or Angular) to coexist within a single interface, MFE provides the clean mechanism we need to achieve full feature parity from the onset. While some features or views reside in the new codebase, others can be subtly sourced from its predecessor. With a little bit of styling to ensure consistency, this experience is completely seamless to users.
We are then able to incrementally replace the frontend in thin, vertical slices without impacting the rest of the application. As features are reimplemented in the new codebase and their former versions are decommissioned, an indirection layer intelligently routes requests and delivers content from the appropriate location.
MFE Adoption and Use
While MFE does offer a means for us to apply the Strangler Fig Pattern on the frontend, this is not its predominant use case.
Though still unknown to many, the concept of micro frontends is not uncharted territory. MFE has been adopted for one reason or another by many major companies such as Spotify, Netflix, Ikea, American Express, Upwork, Capital One, OpenTable, PayPal, HubSpot, SoundCloud, Hello Fresh, and Starbucks. Personally, I have spearheaded more than a handful of micro frontend implementations, including a few that fall outside the realm of modernization.
All of this is not to say that MFE is right for everyone. While some herald it as “the future of frontends,” there are also critics who find it burdensome. Just like anything else we work with, MFE comes with its share of drawbacks, including complexity, overhead, and cross-cutting concerns.
One aspect to consider when leveraging MFE for migrations is that it doesn't necessarily have to be a permanent fixture. If all features are reimplemented and their outdated versions are retired, the micro frontend overhead can be lifted. On the other hand, the team might decide by then that it is time to embark on the next generation of technology. MFE allows modernization to become a continuous practice rather than a reactionary hardship, indefinitely preventing the system from returning to an outdated state.
Implementing MFE
Various technologies can be used to orchestrate the loading and embedding of micro frontends. Often, these technologies also handle routing, state management, and communication between the micro frontends. There are multiple implementation models and an array of frameworks and tools, each with its own unique take on solving the problem.
The biggest differentiator among the various options is how and where rendering and composition take place. Client-side composition tends to be more common, with implementation models such as dynamic module loading, iframes, Web Components, and Module Federation. Composition can also be handled at the server level or provided by a CDN. While there are many out-of-the-box products such as Single-Spa and Luigi, it is also common for teams to roll their own custom solution or implement a hybrid of multiple tools.
It’s important to remember that MFE is a design pattern, not a prescription. It defines the ‘what’, not the ‘how’. As with any transformative endeavor, careful consideration of all the options is paramount. In the context of migrations, not all solutions are created equal. Some options may work flawlessly in greenfield scenarios, but they do not stand up well to the challenges of retrofitting existing code. Finding the right fit is key, and unfortunately, there is no one-size-fits-all.
First and foremost, we must be able to integrate with minimal modification to the old code. Given the complexities of componentization, runtime isolation, state management, dependency management, and other critical factors, some solutions require changes that can inadvertently cascade far and wide. Not only is time spent converting code that will soon be replaced wasteful, but it also presents significant risk. If the code lacks adequate testing, that risk is even greater.
Bringing It All Together
The first time I inadvertently combined the Strangler Fig Pattern with Micro Frontend architecture was purely by happenstance. It was a fairly basic iframe implementation on a transformation carried out years before I became acquainted with terminology for either concept. While my techniques have undoubtedly evolved over time, the fundamentals have remained a mainstay of my practice.
Recently, I consulted for a client specializing in fundraising tools for large non-profit entities. My team was tasked with building the next-generation version of their robust platform. In addition to achieving full feature parity, the replacement product needed to offer a revolutionary set of new features promising to shake up the industry. Not only did our client require a swift product launch, but they also aimed to unveil it at a big industry conference in less than a year. We needed to focus the limited time we had on knocking the new features out of the park.
Determined to meet the tight deadline, we turned to the Strangler Fig Pattern and Micro Frontend architecture. The end result was a beautiful new React application that seamlessly served restyled instances of the legacy features built in an early version of Vue, right alongside the new functionality in one cohesive customer experience, unbeknownst to the user. The new product immediately witnessed a 45% growth in revenue over its predecessor. After the release, our client’s engineering team was able to gradually begin replacing the remaining legacy functionality in small increments as new user stories were introduced in those feature areas. Our approach to modernization in-place deferred cost, reduced risk, and enabled our client to quickly provide value to their customers. This is one example of many.
The journey from legacy to modern is rife with challenges and opportunities. By embracing the Strangler Fig Pattern and harnessing the power of Micro Frontend architecture, organizations can get innovation into the hands of users without all the setbacks. Together, these strategies enable your team to navigate iterative transformation and face the ever-changing technological landscapes with agility and confidence.
Additional Resources
John Lawrimore is a Principal at Dialexa, an IBM company. John carries nearly 20 years of digital product engineering experience with areas of specialization that include modern web development, usability, solution architecture, test-driven development, and Agile methodologies. As a seasoned consultant, trainer, and former professor, John aims to cultivate high-performing teams, help build innovative solutions, and maximize stakeholder outcomes.
This post originally appeared on medium.com.
CTO/CIO Advisory
10moGreat write up John! A fresh take on a pervasive challenge for anyone dealing with old tech!
Senior Principal at Valent Partners
10moPonchai, thanks for reposting! Did reading this give you déjà vu from our WSOWeb project? 😊
Transforming companies at hyper speed
10moHow is this any different than a micro-service?
Skeptic | Technology Leader | Always a Lover | Sometimes a Fighter
10moJustin Steele