Microfrontend — what, why, and how under 7 mins | ELI5
This is going to be one of many stories where I try to explain web stuffs in the best ELI5 (explain to me like I am 5 ) possible. So hang tight, and it shouldn’t be long.
So as the title suggests, let us go over what, why, how on micro-frontends, one at a time.
The What
Microfrontend, which is now being widely adopted across industries, have been around for a while now. It basically means making your different frontend apps, work together and make it feel/behave like a single application.
If you’re from a backend background and you write services, you would be familiar with the microservice architectures. Microfrontend is basically that, but for frontend.
Here you can tie multiple frontend applications, and the end users feel like they are using a single web application.
Here, you have 4 different applications which are working together behind the scene. These 4 can be any frontend apps, built with any frameworks and can be completely isolated. (lets assume we have an angular app in app4, a react app in app2, and vue app in App1).
The Why
Say, you have a web application for your e-commerce business, which showcases the landing page, some products, and prices.
And now you need a payment portal, and you realise this is going to be a crucial feature and you want your customers to have a smooth experience with it. And you also realise that the application you have already, is a legacy software, and it’s becoming difficult to maintain now.
And now you want to revamp your entire product, but you don’t have the time, or resource to do it. So you decide going forward, any new feature on the platform is going to be on this super cool framework that you have come across recently.
Also, you do not want to mess up the current customer experience.
What do you do?
Microfrontend the heck out of your platform, is what you do. You hire a team dedicated to this feature (payment in our case) — build a separate app for that, and pull that in in your Main App.
You are basically giving your users a brand new app integrated with the already existing one.
Now this feature would be super fast, because it doesn’t have a trillion dependencies like your main app, has pretty less bundle size ( compared to your main app) and a very aesthetic look and feel to it (depends on you design it lol).
But what else you ask?
Having a different set of apps help you run different teams independently of each other and the core focus of each team is more narrowed down.
Also since they are independent apps, chances of your App 2 messing with App 3 is significantly less (not zero because you do have a shared state sometimes).
Your teams can work in parallel without having to worry about what the other team is doing.
But do companies really use this?
Yes they do. Ikea, Spotify, SoundCloud, Upwork to name a few.
If it is that good, everybody should use it right?
Well, to paraphrase uncle Ben, with great architectures, comes great complexities.
Since you are splitting your app into various small applications, there has to be some work involved in its state management. State is basically data, which your application uses to do some operations.
A basic example of this is; say your payment app requires some sort of token in order to authenticate the payment. Or it requires the user data to generate the invoice. Now you cant let your users login every time they visit any new microfrontend app. This would clearly give away your sweet little architecture and more than that, some terrible UX.
So there has to be a way to have a shared state across different apps right? — or at least some sort of communications between your microfrontend apps.
Let us have a look in the How section.
The How
We are going to follow a different approach to microfrontend-ing your apps. Microfrontends gained further popularity with Webpack 5’s module federation release. Which involves tweaking your config to accommodate this architecture. But we will take a different route. One that a very well known company Hubspot uses.
iframes
For those who are not aware of what iframe is, it basically houses a different website on to your website. You can you have your portfolio website, and you can contain google.com in to your website. It would act like a container.
You might have seen some places, where youtube videos are embedded in different sites, like this one.
Go ahead and inspect element on the video, and you will see something called <iframe>. Which helps in easily housing this video, or any site for that matter, into your own website.
Now say if you didn’t know about youtube, you would think that this video is part of this website. And tada! thats basically the crux of microfrontend :D
But its easy here because there is no data exchange happening between this site, and youtube. So what if you need to share some data, or in other words communicate with the child App (in this case youtube).
You can do it using PostMessage API. You can pass down data models to your child app, and you can listen to events that the child emits.
In our payment case, we can pass down the user object and token down to child, and once the payment is completed, the child app can emit an event letting the host/parent app know that the payment is complete. And the parent app can then redirect and generate the invoice.
Okay okay. How do you do that though?
So to calm Linus Torvalds down, I am going to show you some basic snippets on how you can get started.
In your main app, where you want to render the child app, you just need a container (preferably a div) and then host your child app in an iframe.
To communicate with the apps, we are going to use Postmate but feel free to use any other library of your choice.
A typical setup of main app
<template>
<div
id="childapp"
ref="childapp"
style="height: 100vh; width: 100%; border: none"
></div>
</template><script>// Postmate sets up an handshake with your child app new Postmate({
container: this.$refs.childapp,
url: `${url-of-your-child-app}`,
name: 'child-app-name',
model: {
// any data that you need to pass to your child.
sampleData: 'tokenABC' },
}) .then((child: any) => { // Handshake with Child is complete /*
now that your handshake is setup, you can listen
to events from your child app.
*/ child.on('getRefreshedTokenId', async () => {
const tokenId = await this.getTokenId() /*
you can also call any child app's function that is
exposed by the child app.
/* child.call('setTokenId', tokenId) })
}) .catch(async (err: Error) => {
// catch errors if any. })</script>
Now lets take a look at the child app, and how that communicates with the parent app.
At root level component of your child app:
<script>
new Postmate.Model({ setTokenId: setTokenIdFromParentApp, // this function is
exposed to parent app
}) .then((parent: any) => {
console.log('Handshake with parent complete.')
const { model } = parent// model has all the data that is passed down from parent.
// you can also emit to parent using
parent.emit('getRefreshedTokenId') // name of the event })</script>
You can also save your connections / handshakes in to a variable and use that across app, to prevent from creating more than 1 connections.
Just use parentConnection = new Postmate.model() or childConnection = new Postmate()
And use these later on.
Once you are done, that is, when you route to a different url, or component, you can kill the connection with
childConnection.then(child => child.destroy())
And …. thats pretty much it.
There will be certain complications related to routes if you want your child route to show up on the browser url. It is outside the scope of this article, and I will let you figure it out.
You can personally ping me if you face this issue and I would be happy to help you out.
Now if you’re thinking, why use the Postmate model to pass data into child app, and not just use browser local storage or cookies.
It is because since you are using an iframe, your child app wont have access to your parent’s local storage. Or cookies.
Hope that clears some things out, and you’ve learnt something new. If that’s true, a clap or two would be greatly appreciated!
I understand this might have been a little over ELI5, and in future I will try to break things further.
To read some more web related stuffs in the ELI5 series, you can follow my works in here!