Our Journey Into μFrontends

Rate this content

Building products using Test Driven Development with React and Atomic Design has become my modus operandi over the years. Some products tend to grow in complexity and it is crucial to have a good workflow to keep them healthy and scalable. The time has come to add another player to the game - enter Micro-Frontends. This talk will share a practical example of this setup, some lessons learned and the bumps that were hit to get there.

11 min
06 Jun, 2023

Video Summary and Transcription

Welcome to our journey into micro-frontends. We integrated products using a dependency called the card tracker. The manual process between teams raised questions about version control. Microfrontends provided a seamless developer experience and allowed for the cleanup of technical debt. The approach also paved the way for a microservices approach in the backend.

Available in Español

1. Micro-frontends and the Falcons and Eagles

Short description:

Welcome to our journey into micro-frontends. My name is Rita, a geek at heart and a software developer at Volkswagen Digital Solutions in Lisbon. Let me tell you a story about the Falcons and the Eagles, and how we integrated their products using a dependency called the card tracker. It works.

Welcome to our journey into micro-frontends. Let's go.

My name is Rita. I'm a geek at heart. I'm also an avid collector of labels, painter of mandalas, master of Kirby and King Dedede. I'm totally convinced to use my bike to go everywhere in the city. Mother of Pedro. He's four, he likes legos, so do I, it's been going great. I'm also a software developer, and I work for Volkswagen Digital Solutions in Lisbon.

This is the amazing crew that I work with. Previously on React Summit, I have already told you a little bit about how we build our products at the SDC. If you haven't checked it out, please go and check it out. But I would like to add a little bit more to that story. So here it goes. Once upon a time, while the Falcons were building and delivering their products, they did a lot of user research. And through that user research, they identified that the dealers were interested in a new feature, something that would bring a lot of value to them. But this new feature, it was complex enough and big enough that it could be developed by its own team. So the Eagles were born. But it wasn't really good enough to have for the same end users to have two different products being used essentially. So we kind of decided, okay, but we would like to have whatever the Eagles are building integrated into whatever the Falcons are already delivering. So how could we do this? Okay, we decided, very well, the Eagles will create a dependency, the card tracker that will get published into a private registry that we can access, and then the Falcons will go and install it. Okay, seems like a good arrangement. So we set up a workflow between the two teams. First of all, the Eagles, they commit, they push, they essentially, they develop and they bring the product to life. They bump their package.json's version to be controlled in which version we are, though. Then we publish this dependency and we wait for a pipeline to run. And we wait, we wait, we wait, but the work doesn't end here. Where does it go? It goes into the Falcons. On the Falcon's side, you need to bump the card tracker's version on their package.json so that you get a new and fresh install, but you also need to commit and push so that you can trigger the changes on the pipeline and the new feature gets alive. It works.

2. Challenges with Manual Process

Short description:

The manual process between the two teams raised several questions. Who would take care of pumping the version on the Falcon side? How do we track it through the backlog? Should the Eagles pump the version whenever we build something? These questions existed only for an ecosystem with two teams, and the bigger the team, the more questions and problems would arise.

It was functional, but there were several issues. First of all, it was a manual process, so there were a few steps between the two teams that needed to be synced. It inevitably questions, what else would race? We published, have we not, whatever. Most of all and the key thing, who would take care of pumping the version on the Falcon side? And most of all, how do we track it through the backlog? In which backlog, the Eagles or the Falcons? You got to sync it. And should the Eagles pump the version whenever we build something? And whenever we deliver, should we bump? Questions. And these are questions that existed only for an ecosystem with two teams. So the bigger the team, the bigger and the bigger amount of questions and more questions you would have and more problems you would face.

3. Microfrontends as a Solution

Short description:

We wanted a seamless developer experience for the Falcons, Eagles, and other teams. Microfrontends seemed like a possible solution. After researching and creating a proof of concept, we chose to use React as our app shell. We integrated microfrontends into a bigger picture and mimicked our product.

What did we want? We wanted to have a developer experience that was completely seamless, that you could have the Falcons and the Eagles and whoever else wanted to join. To be able to deliver and develop their products in a seamless way and provide a good interaction towards the end user. So we were kind of stuck.

But in October 2021, a new hope came along. When I visited React Advanced I met Alex and Ruben. They were talking about microfrontends through their talks and also through the panels. So there was a lot of discussions and I learned a lot. And a little question stood. Could it be that microfrontends were the architectural solution that we could use to fix our problem with the eagles and the falcons?

Coming back to London, to Lisbon, we read a lot. We read some books, we asked questions to Google and we thought, okay, now we know and it was kind of known at the point that microfrontends they were created using the same principles. So they derive from same principles as microservices. So where do we stand with with our ecosystem? We kind of have independent teams. So it's decentralized. All good. We have a clear customer focus so we are able to model our businesses or our domains around business. We have the CICD. So automation and deployment it's taken care of. But we wanted to have those seamless deployments to be able to have independent teams really building and delivering software. So let's see if we can if we can pull this off.

We created a proof of concept and with that proof of concept, it started off from having a set of designs and identifying different microfrontends them. We chose to mix and match bundlers and technologies so that we could also prove to ourselves that it doesn't matter what tech stack you use for your microfrontend as long as you publish your outputs, as you publish your results. And eventually, the microfrontend is completely pointless on its own, almost. It thrives whenever it is integrated into a bigger picture, so you need to assemble it somewhere. And for us, the choice was to assemble it in an app shell. And this app shell was created using just React. Why? Because we didn't want to spend a lot of time learning and trying out all the frameworks that exist for assembling microfrontends. So let's go with React. Let's keep it simple and see how far off we can go. And so we did. We fetched the results from the previous bundling from the cloud, thank you Docker, and we mimicked what would be our product in the real deal.

4. Deploying Microfrontends and Lessons Learned

Short description:

We successfully deployed our microfrontend architecture using React without the need for additional frameworks. While we faced challenges with AWS and defining the boundaries between microfrontends, we learned valuable lessons and were able to achieve seamless deploys. This approach also allowed us to clean up technical debt and pave the way for a microservices approach in the backend. Overall, we are satisfied with the results and believe that microfrontends have our seal of approval.

We were convinced this worked, so let's go for the real deal. That started off exactly the same way. We took the designs from Figma. We identified the microfrontends that we wanted. From our proof of concept, we understood that the best combination is to have ES build and React. It's blazingly fast, it's really cool, but the big difference is that now we were deploying to AWS. So if you deploy in AWS, you put your results on an S3 bucket, all good.

And we repeated the pattern for the microfrontends that we needed to build. We also kept the pattern of an app shell that was built using React, also in AWS, that would fetch the microfrontends from S3 buckets. With this setup, we went live, we went forward with the product, and we learned a lot along the way during the development.

What did we learn? Well, we learned that we had really good experiences, we had mad things, and we had bad things. Let's take those out of the way. AWS was a bit of a challenge because it was a transitioning time, we were changing our infrastructure, the team was new into AWS. So that on its own, it was already daunting. But as you can imagine working for VW, you have a lot of policies and a lot of security restrictions on network. So that posed a problem when trying to get things and having things up and running as we wanted. We were able to, but it took us some time.

When to draw the line between the micro frontends? This was something that we only understood a bit into development, and essentially, it is because we didn't identify so clearly what would be our domain objects. So we needed to have a bit more clearance, not clearance, sorry. We needed to have a little more vision on what would be the objects that would be shared between the micro frontends. And this kind of goes a little bit together with the design system, because, okay, we do have a design system that's set. But sometimes you have to do a little bit of tweak here on this micro frontend and then another little bit of tweak on the other micro frontend. Where do you put it, do you duplicate it? It was kind of sketchy. Another question, using a monorepo or using a one repo per micro frontend? The opinions, they're scattered. We don't have a strong opinion, but it's something that we wonder, have we done the right thing? Should we do it differently? We don't know.

However, what we do know is that React pulled through. So we were able to deliver and deploy a micro frontend architecture using just React. No framework was needed and it's working. So kudos. In this process, since we approached the product as a Greenfield one, we were able to clean a lot of the technical debt, of course, not only on the frontend, naturally, but also on the backend, because we were able to spot a couple of places that we didn't do the best decisions in the past and now we have paved the way for also going for a microservices approach for the backend. Most of all, we have been able to achieve the seamless deploys that we wanted. We have independent teams working together, delivering and bringing the best experience to the end user in an autonomous way. All in all, I would say that microfrontends do have our seal of approval. So thank you very much. I'll see you soon.