{ Simple Frontend }

How to organize and split your frontend applications

Introducing a decision tool to guide you through the process and make an informed decision, supported by end to end code examples.

Jeremy Colin Jeremy Colin
Nov 26, 2024 - 5 min read
#Frontend
  • About to start a project for a large frontend applications?
  • Already have one that outgrew your initial project setup with distinct use cases that are now entangled and difficult to evolve independently?
  • Or you find yourself with a myriad of frontend applications in different repositories that have become a maintenance hell like this?

You are probably asking yourself: how can I keep or regain my initial high development velocity while maintaining my existing frontend applications?

While the answer is unfortunately “it depends on your setup and goals”, I have created a tool to help answer this question. You can access it for free here. In this post, I go into more detail about the reasoning behind my recommendations in the tool.

Micro-frontends and module federation: “just” tools

There is a lot of content and talks on how to scale your frontend applications with “micro-frontends”, and more recently, “Module Federation”. While these will help you, they should not be your starting point.

Micro-frontends are a set of frontend architecture patterns. They are designed to help you break down large user interfaces into smaller, more manageable and independent chunks. They are essentially an extension of microservices concepts to the frontend.

Module federation icon

Module Federation is a concrete implementation of microfrontends thanks to a module sharing solution. In its 2.0 version, module federation is available for all modern bundlers, making it a fantastic tool for implementing micro-frontends.

With that out of the way, the place to start is not with tools, but with business and organizational goals.

What is your primary goal?

What is the core problem you are trying to solve?

  • Are your teams spending an awful lot of time doing duplicated operational and maintenance work?
  • Is it complicated to ship features that touch multiple frontend teams?
  • Are the user experiences and interfaces of your products becoming increasingly inconsistent?

I have lived through all of this.

Maybe your use case is different: you have separate development workflows by design, but now you want to start sharing logic between your applications.

This first answer will help you decide whether you should use a frontend monorepository or separate repositories.

I have covered some of the advantages of using a monorepository here, the biggest ones being simplification, consistency and easier cross-team contributions through a centralized and opinionated setup.

In some cases, such as, for compliance reasons or if you want to keep a high degree of technical autonomy between teams, separate repositories make sense.

Frontend monorepository architecture

How do you want to serve & split your applications?

This question helps inform the underlying technical choices such as the routing setup for your frontend applications. Do you want your applications under different domains?

Or do you want your applications under the same domain at different URLs path?

The answer should come from the business. You can use either a single repository or multiple repositories for both use cases.

Splitting your applications across different URLs is referred as micro-frontends vertical split. Vercel recently published a great blog post explaining how they migrated their applications to a vertical split setup.

Micro-frontends vertical split

Sharing dependencies between applications

The last thing to consider is how you want to manage shared dependencies between your frontend applications. This will help you decide whether you should use module federation.

Packaged dependencies

Packaged dependencies are dependencies that are built and published to a package registry. These can be UI modules or a horizontal enablement integration such as analytics.

With a monorepository setup, you can skip the build, publish, and update process, which can save a lot of time and effort.

When you have separate repositories, you have to manually manage dependencies versions and update them in each application that consumes them.

Runtime dependencies

Runtime dependencies allow you to share code and resources between multiple JavaScript applications at runtime without having to package them in each application.

Runtime dependencies are much easier to synchronize across applications as you can simply redeploy them for each application to have their latest version, eliminating a lot of tedious work. This is a big advantage when you want to release hotfixes or new features for these shared dependencies. Of course, this adds some risks for these apps deployments, so a good quality assurance process is necessary.

Common use cases include sharing global UI components such as a header or footer, as well as horizontal enablement such as analytics, A/B testing, or observability.

This is where Module Federation comes in. The second version of Module Federation is supported by all major bundlers and helps you easily declare and consume runtime dependencies.

Runtime dependencies are referred as micro-frontends horizontal split.

Micro-frontends horizontal split

Recommendations decision tree

You can access the decision tree tool here and below you can see the full decision tree diagram. The boxes with recommendations on the right are clickable and will open the corresponding example repository on GitHub.

Hopefully you now have all the tools and information you need to make an informed decision on how to organize and split your frontend applications! If you would like to discuss this topic further and discuss your specific use case, please feel free to contact me.

Related posts