One random day not long ago, I started hearing joke after joke about “micro frontends” — sort of how I first learned about Toast. I didn’t understand the source until asking around, which uncovered this article from Cam Jackson.
In this article we’ll describe a recent trend of breaking up frontend monoliths into many smaller, more manageable pieces, and how this architecture can increase the effectiveness and efficiency of teams working on frontend code.
I’d argue it should read “front-end monoliths” and “front-end code,” but I digress already.
The idea is similar to microservices, but for the front end. So, instead of one big front-end architecture (e.g. a React app), different parts of the front end are developed entirely independent of one another, have no dependencies on each other, and can be worked on and deployed independently.
It’s one of those things where you can’t quite tell if it’s really an interesting foretelling of the future, just a niche architectural choice that happened to work for a handful of large organizations, or even just a theoretical option.
The first place my mind goes is consistency and DRY-ness. Anywhere I’ve worked, these things are a big deal and it seems like the industry at large has had endless front-end problems with shipping designs that start and stay consistent and cohesive without repeating itself with shovelfuls of technical debt. Independent front-ends sound like they might be a problem if Team B is being blocked by Team A for something not directly related, but then it introduces the problem of Team B’s output drifting towards inconsistency with Team A’s output.
The article itself talks about a browse/search landing page, a details/ordering page, and a profile page, with all three of those tackled by different independent products/teams. It sounds kinda cool and interesting to me, and it also sounds like those teams better sit right next to each other at work; otherwise this app is going the way of Frankenstein’s monster in two weeks. Styling is only lightly addressed with a, “I dunno, do a good job” sort of vibe. Teams struggle with this when they are all on the same product, so I’d have huge concerns here. The first thing I’d try to solve if this is being discussed seriously would be a design system that transcends all of it and that everyone uses without fail.
And what if those micro front ends co-exist on the same page? Use <iframe>
, the article says. I can’t see a world where that leads to a good user experience. (iFrames are slow, especially many of them all booting up their own worlds — and what about elements that might overflow bounds like tooltips and menus?)
The other integration options… isolating them to their own bundles or even native web components sounds a bit better. But still, the idea of siloed development where a React component might be slapped on the same page as a Vuew component seems like a huge user penalty for a pretty specific organizational problem. Not to mention you’re losing the benefits of a shared understanding of a codebase and the benefits of a deeper technical understanding of a smaller set of tools.
I’m probably not characterizing all of this fairly, especially because the idea is rather new to me and I’ve never worked like this before.
Nader Dabit has a follow up article: Building Micro Frontends with React, Vue, and Single-spa. Just so I’m not mischaracterizing that: The idea really is that you might build a React app and I build a Vue app and we’ll slap ’em together on the same page. I definitely come from an era where we laughed-then-winced when we found sites that used multiple versions of jQuery on the same page, plus one thing that loaded all of MooTools and Prototype thrown on there seemingly by accident. We winced because that was a bucket full of JavaScript, mostly duplicated for no reason, causing bugs and slowing down the page. This doesn’t seem all that much different.
Joel Denning points out in an AMA on the subject:
I’m pointing out that we’re in the “hate without closely examining” stage of the idea. It’s entirely possible that after legitimate, close examination that the idea still fails. But too early to tell.
Fair enough.
Sorry about piling on. 😣
— Chris Coyier (@chriscoyier) June 20, 2019
It’s… components. They’ve invented… components.
This seemed like a radical idea to me at first, as well, but it honestly does make a lot of sense. However, I’m not sure I’d go as far as some are suggesting. One of the benefits of microservices is that you can truly have separate and independent teams working on different services, all using whatever languages and/or frameworks work best for that team. The end result is usually just some JSON response, so the underlying architecture matters little.
The same is not necessarily true with micro frontends. While you could use React on one frontend, Vue on another, etc., doing so actually puts a burden on the user: they have to download all of these different libraries as they traverse through the entire site. I don’t think the same flexibility of microservices exists here for that reason. All the frontends should conform to a common client-side framework.
However, aside from that, there’s still a lot of potential value. ASP.NET Core, for example, has Razor Class Libraries, which can be used to share common interface elements such as headers, footers, or various other components. Other frameworks might have similar functionality. That combined with CDNs, both public and personal, can give each frontend a common base out of the box, allowing the actual frontend to focus on only what it needs to specifically provide.
The problem with a monolithic frontend is the same as a monolithic backend, a change to one area requires deploying the whole shebang. I can see real tangible value in having discrete frontend units that can be deployed and changed independently of each other, assuming, again, that they all work from a common base to ensure consistency.
A good example of this in the wild might be CAPTCHA or various “Sign in as” features. They’re basically an endpoint with an importable widget that connects to it.
To make this work across a large scale app, I think teams would also need to own pages in addition to just features.
Using registration as an example:
Team A might develop an endpoint, UI components, and a dedicated page for registration with the understanding that certain guidelines need to be met, e.g. how the components use screen real estate in a modal even though they’re not using it that way.
Team B, who owns the home page, could then USE the endpoint and UI components developed by Team A to implement a registration modal on the home page.
I don’t know if this would actually work in reality; a designer without a thorough understanding of how modularity works in practice, or a developer who writes brittle CSS could cause a lot of problems for other teams.
A micro front-end should only use what it needs, not a monolithic front-end tool like react, vue, jquery. These beasts should be broken into linkable parts to be useful: rather than load the whole beast, link in only the pieces that get used. So the problem here is that with a dynamic interpreted language, it is hard to know what pieces will be used, and so the beast grows ever larger, and is monolithic and must all be loaded to use any of it.
If only the pieces needed were loaded, then iframes wouldn’t be slow. Iframes that load whole monoliths, over and over (for each iframe, that is) are always going to be slow, and caching won’t help much if each uses a different monolith.
The other problem, of course, is that they have to be loaded over the internet (at least the first time), and separate requests for lots of tiny pieces is slower that loading the whole monolith in one fell swoop. So front-ends really needs a linker step, where you can include the tiny pieces you need into the source of the page: instead of referencing whole monoliths, you link the pieces you need into the page source, and make your own microlith for each iframe…
The end result, though, for a whole set of pages composing a site, is that the sum of the microliths might be greater than the size of the monolith. So there is a tradeoff between page speed and resources consumed, and site speed and resources consumed.
Personally, I don’t use any of the monoliths because of the load times, I just code in plain javascript, and using frames where appropriate for separation of concerns hasn’t been a performance issue.
This somehow resembles the reaction people got in the early days of CSS-in-JS.
I truly think this simply an idea. Whether it gets to the point micro-services got to will be something to watch. I for one, don’t see how using multiple frameworks in a single app could be beneficial without building other tools to truly isolate them on the browser and to prevent unexpected UI bugs in a real world application. Is the value of this approach truly more beneficial than using something more traditional like our current design systems and or storybook driven development. I’m not sure, but I do think there may be a place for it for a system such as this. Maybe it’s not the way the concept intended for it to be. But somehow the idea of having multiple teams working on different UI and codebase seems a little magical, I love that idea. I think this is already possible though, with a little GIT management, and thought through dev cycle I think we can achieve the benefits of “micro front-ends” that all come together at deployment. Does it warrant a complete architectural change, restructuring and or team dynamics, I’m not sure. But I think we’ll only know once we’ve justified enough to put it into practice. Who knows
We moved to this approach for a large project a few years back, it worked great with about 5 UI teams handling about 20 sub-apps/pages. It works well when you want to transition or use alternative/new frameworks, as the roll-out can be gradual with minimal bleed into the current implementation. Version management across the codebase was key, though it was difficult to maintain consistency in certain areas (e.g. styling, components) but those have more appropriate solutions.
It’s not perfect, or for all cases, but it has many benefits.
I learned about microservices in a course and I am really hyped about it. But front end microservices is a totally different idea and it blew my mind. Gonna look for more details, thank you…
My biggest concern in all of the conversations is providing viable solutions for the scope and context of the problem. What I hate is the dismissive nature of some of the critiques; The sort of “what is this trying to solve scoff just use Iframes!” or “So this is web components then?” Or any sort of “tsk, tsk, any good developer knows…” stuff.
Let’s say that we have a large application with a bunch of features. The “parent” app is owned by one team and the “child” features are all owned by different teams. There are 30+ features owned by 15 teams. Not only that but those 30+ features may be reused in other “parent” apps. Today the direction is “make the features an NPM package” and then the parent apps consume those dependencies, compile them, and optimize them in different ways to produce a “monolithic” app (… using this term even though there are chunking and splitting options).
The problem becomes that the parent apps teams are now gate keepers to all the other child feature teams. Nothing can go out to a user without one team actively and directly consuming another team’s work. The other problem is version conflicts. It can end up where all 15 teams have to update all of their products in order to implement a package update that was really only needed by 1 child feature.
Right there you have teams feeling stifled in not being able to get product out the door in a timely manner and other teams feeling overworked for something that isn’t their problem. You can claim that as a cultural problem, which I’ve heard people say; “This tries to solve project management and team collaboration problems, maybe we should focus on culture instead of technical solutions”
The problem is that we’re not looking at developers as users. They are people who want the same things that the users of their products want; Ease of use, to complete their task quickly, to feel in control, minimal effort for maximum outcome.
Whether it’s microfrontends or another solution I want to see us treat developers like users. I believe that the developers’ user experience is important too. If there are solutions outside of microfrontends to tackle this then let us specify concrete examples, not just rhetoric and anecdotes. Let’s analyse those examples for gaps and usability challenges. Then let’s produce more usable solutions. My fear is that too many people are looking at the space, not having the exact problem other teams have, and dismissing it as “not a real problem”.
It is a very real problem. Microfrontends might be one solution.
So I work in an organization that builds a CMS, the UI is complex, the code base is big. As all big apps it has legacy frameworks, its Wicket combined with ExtJS, angular.js and now Angular, and now we are supposed to combine it with React apps written by teams from a company that acquired us. its way to big to consolidate it all in 1 framework, it would take years (combined with new feature development, or we die), by which time a new framework will have popped up that is better. My point is that in big enterprise apps like those there will always be technical debt, multiple frameworks coexisting, and no time to consolidate them. Using this micro front-end approach splitting up these parts (in our case using iframes) and allowing them to communicate via a well defined api layer allows for better separation and refactoring later.
But that is for big apps, who would do that for a single webpage?
take a look:
https://single-spa.surge.sh/