Here’s how the layers work:
Level 1: The Common Utility Microfrontend This foundational layer contains utility functions, helper methods, and other low-level abstractions that can be used across all other microfrontends. This includes dates/time utilities, API request handlers, and formatting functions. By centralizing these, we eliminate code duplication and ensure that all microfrontends use the same logic for common tasks.
Level 2: The Core Components Microfrontend This layer houses common UI components and shared business logic that multiple workloads depend on. A good example is a specialized list component that encapsulates the business logic for API calls and user interactions. Instead of each workload team building their own list component, they can import it directly from this shared microfrontend, ensuring consistency and saving development time.
Level 3: The Workload Microfrontends Each business function or "workload" is developed as a separate microfrontend at this top level. These microfrontends are the consumers of the two lower-level microfrontends. They use the utility functions from the first level, and the UI components and business logic from the second level as building blocks. On top of this, they add their own functionalities to create the UI for their respective workload management sections.
Part 2: Dynamic Module Federation for Flexible Deployments
One of the most powerful features of our new architecture is the use of dynamic module federation. In a typical setup, the URLs of the remote microfrontends are hard-coded in the configuration. However, this is not ideal for enterprise applications deployed in multiple environments (e.g. development, staging, production), where the URLs will be different. Also with “hydra” (an internal initiative of multi deployment), even in the same environment, we can have multiple deployments (eg: deployment for multiple regions).
With dynamic module federation, we can load the URLs of the microfrontends at runtime. This means we can build our application once and deploy it anywhere, with the application dynamically discovering and loading the correct microfrontends for that specific environment. This provides huge flexibility and simplifies our deployment process.
Quantifiable Improvements in Scalability and Performance:
Beyond theoretical benefits, our microfrontend adoption has yielded concrete, measurable gains in scalability and performance:
Accelerated Build Times: Our microfrontend builds now complete in approximately less than 5 minutes, a dramatic reduction from the previously unmanageable build times of our monolith. This significant reduction in build time directly translates to faster iteration cycles and quicker deployment of new features.
Enhanced UI Load Times: By leveraging CloudFront for rendering microfrontend bundles, we've achieved load times in milliseconds. The benefits of edge location caching have made the UI significantly more responsive and performant for our users.
50% Increase in Development Velocity: The abstraction and modularization of business logic and UI for common components within the Core Components Microfrontend have led to a 50% increase in development velocity. This allows our teams to rapidly develop new workloads by utilizing pre-built, standardized building blocks, greatly speeding up the time-to-market for new features.
Improved Testing Cycles: The initial challenge of "slow testing cycles" has been effectively addressed. Our current microfrontend setup has led to improved Component Tests running times, further accelerating developer feedback loops and enhancing code quality.
Unique Architectural Alignments for a Seamless Transition:
Druva's multi-level microfrontend approach goes beyond a simple technical migration; it represents a strategic alignment with our core architectural principles. This alignment has greatly streamlined and simplified the transition process.
Mirroring the 'Unity' Framework: Our back-end teams had already embraced a 'Unity' framework, which streamlined much of the repetitive work at the backup set and job level that various workloads and teams used to handle. This approach of abstraction, modularization, and reusability became a foundational part of Druva's engineering DNA, enabling greater efficiency and consistency across teams.
Our multi-level microfrontend architecture mirrors this successful back-end strategy on the UI side. This alignment provided a significant advantage, as it allowed us to extend our architectural philosophy naturally to the front end. The shift from a monolith to an advanced, multi-level microfrontend setup became a smooth evolution, simplifying the process while maintaining consistency in our design principles.
Conclusion
Transitioning from a monolithic UI to a multi-level microfrontend architecture has been a game-changer for our team at Druva. By breaking our application into smaller, reusable, and independently deployable components, we’ve dramatically enhanced our development speed, scalability, and maintainability.
This structured, layered approach has enabled us to fully leverage the advantages of microfrontends while avoiding common challenges like code duplication and overly complex data flows. If your monolithic front-end is holding you back, we strongly encourage exploring this transformative approach.