Lucas Dohmen: Hello, and welcome to the GOTO Book Club. Today, we will talk about “Building Micro-Frontends” and I've invited Luca the author here. Welcome to the show, Luca.
Luca Mezzalira: All right. Thank you for having me.
Lucas Dohmen: My name is Lucas Dohmen. I'm a senior consultant from INNOQ, and I'm also very interested in frontends and how to build good architectures for web applications, especially big ones. Luca, maybe you can introduce yourself.
Luca Mezzalira: Sure. My name is Luca Mezzalira. I'm Italian but based in London. I'm a principal solution architect in AWS and in the last seven years, I have explored the micro-frontends topic quite extensively, not only writing a book but also building multiple applications and helping customers to implement these architecture patterns across different industries, seeing different challenges and figuring out how to overcome them. So it has been a very interesting journey so far. So I hope that will continue in the future.
What is an app shell?
Lucas Dohmen: Awesome. Micro-frontends is already a word where different people have different ideas of what it means. But before we get into that, I would say let's first look into the app shell, I think most people are not aware of what exactly that means. Can you explain what an app shell is?
Luca Mezzalira: Sure. The application shell is the first thing in a fat client, as it is called, or rich client-side application that you usually download. So when you type your mysite.com, the first thing that you download in that case is an application shell. The application shell is unaware of the business domain, or it should be as much as possible because that is a common part. And what it is responsible for is loading the micro-frontends and routing the URL basically on where the user wants to go, and then loading the right micro-frontends associated with that. It's also responsible for delinking, that usually comes for free out of the box when we are implementing the application shell and is usually used either within the horizontal or vertical split. So the application shell, when we do on the client-side, we can decide to go with horizontal or vertical or both, as we said before.
The interesting part is that with the very light implementation, there are several technologies that you can handle. In my humble opinion, usually, if you are capable of keeping that as framework-agnostic as possible, it opens up also the possibility in the future to evolve the micro-frontends without the coordination of having the application shell that is holding you to experiment.
What framework to use for micro-frontends?
Lucas Dohmen: Let's dive into that topic as well. Because I think one thing that I've come across a lot is the question, "Can I use different frameworks for different parts of my micro-frontend? Or should I use the same one for everyone? Should I use Angular and React mixed, and some use Angular and some React? Or should I always use React for all of them?" Not looking at Angular or React right now. But where do you see both in the vertical and in the horizontal split with the app shell, how do you see how you can handle that?
Luca Mezzalira: Despite the architectural pattern that you're going to take on micro-frontends, I would say that is a misconception that was raised by the community for several years now. The challenge I see, and usually is this example that I made. So imagine that you have a single-page application. Technically speaking, you can mix React and Angular. And I remember back in the days when React came out, there were some experiments on that using the React library as UI and the rest of the Angular framework for the state management and the rest of the application.
Now, despite that you can, it doesn't mean that you have to. Therefore, in my opinion, there are certain situations where having multiple frameworks might help with micro-frontends. So when you are migrating, for instance, from a legacy application to a new one, or if you are migrating an application from an older version of the framework to a new one, what you want to do, instead of going stealth mode for a month and then deliver something in front of your customer, is taking a vertical of your application and start to iterate on that. Deploying production alongside the previous application and starting to generate value for the users because we are going back to the real scope of why we are developing code. And that's where I can see for a certain period of time because I know that is a migration, a mix and match of frameworks.
And another option could be when you are acquiring your company. So if your company's acquiring another one, and you want to immediately see the value of your investment inside your, let's say, brand, inside your umbrella, you can do that. And you can easily have another, let's say, technology that is developed by the other company that is living alongside your application. That is another situation. Overall, I discourage this practice unless there is strong reasoning behind that. Because, obviously, it’s going to have an impact on your users. And at the end of the day, we know that for a certain type of workload, think about, for instance, e-commerce, the first byte is quite important because it could generate more revenue or not. And I know that sometimes it could seem silly, what I'm saying, that one second could generate millions in revenue. But in reality, we have quite a lot of companies that prove that that is true. And therefore, it's very important that we optimize our application, despite the architecture we're using.
Lucas Dohmen: I agree. We should not go to a multi-framework solution because we are downloading way too much data. And it will also be complicated for things like server-side pre-rendering and stuff like that. I think that a lot of people that are doing architectures for the frontend are paying not enough attention to the fact that you already mentioned — migrations. If we are going into a situation where we need to do a framework update that is a breaking change, for example, and we are forced to do it across our entire application, then we are paying all the costs that we have for a monolith. Because then we need to update all at once. And that might be costly.
And the same goes for if you remember something like BackboneJS, that was the first framework I built a single-page application with, nobody would use it today, I would say. And sometimes those frameworks go out of style. And we cannot say which one will maybe be at end-of-life by the people behind it. It's not very likely that React and Angular will just disappear because there are so many applications written in it. But we should at least keep it in the back of our minds that this might happen. And that we have a strategy, if that occurs. And especially for the framework updates, the breaking changes will be something you should pay attention to, in my opinion.
Luca Mezzalira: Yeah, I fully agree. And also, because often we need to think about if, technically, architects and developers are keener to work with modularity, the business instead wants to work with agility. So they want to drift the direction in the way that they want. And if we link agility with modularity, basically, you have exactly what we are talking about here. You have the possibility to take the drift of the organization towards your architecture, and therefore your code, and shift the way how you're working today for having a better future tomorrow. That is, let's say, probably the key thing that an architect should do, try to map the business characteristics towards what we're trying to build. But yeah, I agree with you in your mindset.
Lucas Dohmen: App shell would be one integration method. One other thing you brought up on the client-side horizontal split was the Module Federation, which is a feature from webpack. Can you explain what it does on a high level, not on a code level, because it's always a bit tricky on a format like this one, what it means and what it does?
Luca Mezzalira: Indeed. Yeah, sure. So Module Federation is an official webpack plugin that is available from webpack 5. The interesting part that it does is not mainly for micro-frontends. The idea behind Module Federation is the fact that it’s a transport layer for bundles. And that opens up quite a lot of opportunities, not only on the client-side but also if you think about cloud or server-side, you can still use Module Federation, no problems. The interesting bit for micro-frontends is that if I talk about the transport layer for bundles, the bundles could be an independent piece of code. And therefore, it resides very well with also micro-frontends. And that means potentially, I can use Module Federation for composing my micro-frontends. What it does is exactly this. I take a bundle that is independent, and I, let's say, load it inside another application. That is exactly what we want to do with micro-frontends.
The other great thing that Module Federation does, is taking care of all the dependencies. So one of the challenges you have when you deal with, let's say, your own implementation of micro-frontends is how can I make sure that everyone is using React 15 or React 16, or the same version of a framework or library whatever? Module Federation obstructs that for you but goes even further, providing you the possibility to, let's say, create a scope around the same library with different versions. So if a team wants to use, I don't know, MomentJS with an older version, compared to the rest of the application, they can do that without crashing because the scope is different. And that is another great functionality of Module Federation.
Lucas Dohmen: But doesn't that mean that the build of those different subsystems or different micro-frontends are bound to each other, or are they still independently buildable? So can I just build the component that does the product view, for example? Or is that not possible anymore?
Luca Mezzalira: It's totally possible. Because the whole point of Module Federation is moving away from the concept that I need to centralize the build of my elements. I can use Module Federation. There are two concepts that are key, the host, that is the container of, let's say, another bundle, and the remote that is what is loaded inside the host. The beauty of this approach is that you can create multiple applications completely independent that are living inside their own work, and then load them together at runtime. And all the loading parts are handled by Module Federation. Let's assume that you're using an S3 bucket with a CloudFront distribution in front of it, you deploy your micro-frontends tens of times per day in S3, and every time that application shell is loading with Module Federation, is going to go to the latest version of your micro-frontend. The beauty of this is you're completely independent despite you're using webpack.
Lucas Dohmen: All we need to align on is the build tool that we are using. Right? So we are bound to the same version of webpack for all micro-frontends and not webpack 5.110 or something, right? Okay, cool.
Luca Mezzalira: No, no, it's just webpack 5. It should be retro-compatible. I didn't try that, but to be honest, I never heard anything like that.
Use iFrames for a horizontal split?
Lucas Dohmen: Okay. So the second approach that you outlined in the book is using iFrames for a horizontal split. So I think a lot of people when they hear iFrames, think this is like an outdated technology that nobody uses today. What's your take on that?
Luca Mezzalira: I agree in certain contexts. In others, they are solving quite a few problems. So iFrames, yes, it’s true they are not new but they are the safest option that we have to create strong boundaries and have better control for our code. So if, for instance, you acquire a company and the code that maybe is an old jQuery with other things that you want to put inside your brand new micro-frontends application, but you don't want to have the headache to go through the code and build anything, you take the build that is available currently in the application, you move in your server, and you use an iFrame to basically protect the rest of your application. That is a nice way.
There is a micro-frontends framework called Luigi framework that was created by SAP that is using iFrames for isolating the different contexts. And usually, what they do is use this iFrame, there are not many per view, there are three or four. And they're using that because they are sure that whoever is developing the code is not going to clash with the rest. And they provide a set of facilities in this Luigi framework for the communication part, retrieving the authentication and stuff like that. The other option that I've seen iFrames very useful is on the security side. Because there are certain, let's say, industries that require a strong set of securities. And with iFrame, you can fulfill them very easily. And therefore, I agree there are several drawbacks on iFrame. They're quite heavy and so on and so forth, but there are situations where iFrames can be a valuable option.
The other thing is currently, the TC39 is exploring a proposal that's called ShadowRealms. They changed the name recently. And the idea is basically having a glorified iFrame but without all the burden and the problems that we have with the iFrame. So you don't have to have the full structure of the wind of the object and so on. But you have, like, a light iFrame with all the benefits of creating boundaries around your code.
Lucas Dohmen: I've never seen anyone use iFrames to integrate within one company. But I think, especially using it between companies if you are integrating something from a different company, then iFrames are a very good solution. I think a good example of that is Google Maps. Everyone uses iFrames to integrate Google Maps, right? They don't realize it because they put in a script source. But it's a good way, for security reasons, to split out this application, and don't give it access to the entire DOM that you have. But I would say it's rather an unintuitive way to integrate within your company where you have higher levels of trust, I would say.
Luca Mezzalira: Yes, it's true. But very often, in large organizations, I've seen used iFrames despite there being now these other options for security reasons.
Lucas Dohmen: So one other thing is web components. And I think this is also one of those words where people are not entirely sure what it means. Can you explain what the pillars of web components are?
Luca Mezzalira: Web components are an API standard that is available for developers to create components that are compatible with nowadays all the browsers, if not, the majority of them, and is providing some utilities like custom components and Shadow DOM. And those two things are quite key for micro-frontends. So the custom component is the possibility to create your own components that contain your code. And the interesting bit is you can have it in Light DOM or in Shadow DOM, depends on which path you're going to take. And the main difference is the Shadow DOM basically is completely decoupled from the main DOM element. And that means, basically, that you can, for instance, have also some duplication on, classic example, CSS style. They are not going to override the one that is available or be overridden by what the application is using. The Shadow DOM is basically like a nice black box that prevents someone from accessing it.
I think the interesting part of web components is that nowadays if you're using them they are compatible with any framework. So if you're making an effort for building some elements with web components, then you know that if today it's React and tomorrow will be VueJS, you will be able to reuse that part of the code. That is great. In fact, also in my book, I warmly recommend them if it's possible to use them for creating design systems. Because that basically will allow you to reuse a portion of your code and your application despite the underlying UI framework could change. That for me, in my head, creates also this concept of evolutionary architecture the web components can provide.
The only challenge I have seen so far with web components for micro-frontends is that often developers are overlapping this concept of components and micro-frontends. And that is a risk because sometimes you might hear people say, "Oh, yes, we are using micro-frontends. And we have a gazillion of micro-frontends in the same view." But in reality, they're using components. And a rule of thumb that I try to rationalize lately probably was towards the end of the book, I was trying to figure out how I can explain easily the difference between components and micro-frontends. And the idea is, I think the key here is the extensibility factor. If you think about the component, usually the container is providing some context for the component to behave. In that case, you pass maybe, I don't know, the labels, the localization, the type of behavior you expect from the component, and so on, so forth.
In micro-frontends, you define the input and output. Worst-case scenario, you can inject an event emitter or, let's say, something that's very not domain related, but the micro-frontend owns his narrative. He knows how to build, he knows how to render, he knows everything, how to behave. But it doesn't have to be instructed from the container. Therefore, there is no leak of domain outside the micro-frontend. And that is, for me, the key difference for understanding if you're dealing with components or micro-frontend.
Lucas Dohmen: But you already mentioned the problem with CSS, right? So if I take a solution with a client-side approach with an app shell, then I might have collisions in CSS class names, for example. So one approach would be to use Shadow DOM, as you already outlined. Are there any other approaches that we can use for, yeah, getting out of trouble there?
Luca Mezzalira: Yeah. Another idea that is quite simple to implement, whether you're using web components or not, is using prefix. So if you divide the work that you're doing in multiple teams, every team might have a name or a domain that they’re representing. So if they prepend the class name that they want to use with their own unique name, they can then have uniqueness on their class names, that decreases the risk that there would be a clash.
One thing, for instance, I was using material UI for a demo and I was using micro-frontends, and I have to make sure that they didn't clash together because it was material UI across the entire application but with different parameters and everything. So I don't want the same style or class name that was rendering one way in one part of the application to clash with another one. Therefore, in that case, using prefixes, I was able to decouple, basically, the two styles. And although I might have a style that by default would clash together in the application shell, they weren't clashing in reality because there was a prefix that was creating uniqueness to all those.
Lucas Dohmen: One thing I wondered when I read the book, and I wonder again now is how do you handle things like pattern library? So if I want to do something like a shared style between all the applications they have a certain amount of styling that is shared between everyone and a certain amount that is very specific to one part of the application. Right? So how do you handle that both in Shadow DOM and in something like BEM that you just mentioned? How do you do that?
Luca Mezzalira: Usually, in Shadow DOM, you have fewer problems because they are encapsulated. So in that case, you can make your own decisions and every component won't clash with each other because it's not even in the same if you want scope of the application. On the other side, BEM basically provides you with a more granular way to describe the element that you're styling and it goes up to a certain granularity that makes it more difficult to have, let's say, redundancy on names. But if that happens, the prefix strategy helps a lot. Because then at the end of the day, if you're using the same button but with different, I'm gonna say, styles or parameters that you want to use, you can do that without any clash. Because you are going to basically create your way to handle one thing. And then you can supplement, as you described before, with your own style for that specific portion of the application that requires different styles. So you can really do mix and match with just this simple implementation.
Lucas Dohmen: So maybe this is a bit too deep into the technical part. But if I imagine that you have a page that consists of the app shell, and then three sub-parts that are split, that are different parts of the application. And each of them has its own Shadow DOM. So do you include the basic styling as one CSS file in each of the Shadow DOMs and the app shell, and then add specific styling to the sub-parts? Or how do you do that in practice?
Luca Mezzalira: If you go in the part that you include all the base elements, obviously, it's going to have more kilobytes per download for the users, but you guarantee that they are completely independent. So potentially, if tomorrow one of the team is using an older version of the styles you will still provide an independent element that can be updated at some point. The moment that you start to share anything, style, code, whatever across those three independent parts, then you have a risk that there is a runtime error that you didn't pick up in your environment or in that environment because it potentially could be different. So ideally, you need to understand if that is the trade-off that you want to take, or if you spend more energy and more effort making sure that everything is still there on time, it's not going to be locked from the customer.
Lucas Dohmen: Okay, good.
Luca Mezzalira: It's up to you to decide where you want to spend your effort. It could be a simple, “Okay, I have a bit of duplication, is 10 kilobytes more. That's not the end of the world”. Or “No, that 10 kilobytes, I really need them. And therefore, I need to find a way to optimize my pipeline to make sure that I'm not going to create issues at runtime”.
Lucas Dohmen: Very good. So one thing that we did in one project was that the base style was available versioned at a URL, and you could use it in the different parts of the application. And then you can take advantage of caching. So at least if everyone is on the same version at that point in time, you only download it once. But yeah, that's also an approach where you can maybe find a middle ground between those two approaches.
Luca Mezzalira: Oh, yeah. Of course.
The difference between SSI and ESI
Lucas Dohmen: So talking about the server-side part, I think one of the things that a lot of people have never heard about is SSI and ESI. Maybe some people heard about SSI a lot of years ago. Can you first explain what ESI and SSI are?
Luca Mezzalira: Yeah. So SSI and the ESI are server-side includes and edge-side includes, those are markup languages that are basically using a mechanism called transclusion. Transclusion is an algorithm. What it does is very simple. You have a placeholder element that when it’s parsed by the engine is going to be replaced by more concrete elements. For instance, imagine that you have a cart element that you are describing with that placeholder. And then when the engine is going to parse that markup element it’s going to replace that with a div element, maybe, I don't know, an image that represents the icon and some things. That is basically what it means.
Those are running either edge-side include on the CDN level, or server-side include on the server level. I think server-side inclusion is quite an old technology. So it's not anything revolutionary but allows you to work at the server-side and compose multiple elements because there are servers like NGINX, for instance, that are allowing you to use this technique for composing your page and provide a final output for the user. The edge-side include instead is a markup language that was created back in the days by Akamai and Oracle and a few other companies, that is available in certain CDN providers, not all of them. And the other problem is the ones that are supporting ESI sometimes are not even supporting the full implementation. Therefore, if you think about migrating from one CDN that has the full fledge of specification implemented to another one, you might think twice because you don't know if everything is supported.
The other problem of ESI more than SSI is the developer experience. That I think is quite important. In ESI, there aren't many companies that are providing a smooth developer experience. So you need to test against your CDN. Akamai, for instance, is providing a Docker container that basically allows you to test on your laptop how the CDN node in Akamai would render your application, but it's the only company currently that I am aware that is doing something like that. Usually these techniques I have seen use where you have, let's say, more static content on the UI.
Lucas Dohmen: Very cool. One thing I noticed when I read the book is that one approach that we at INNOQ use a lot that is very focused on vertical splits is not really described in the book. I wanted to get your opinion on where you fit it into your frame of mind. I added it to this as well.
A few years ago, we wrote this guideline called "Self-contained Systems," where we describe how you can integrate multiple vertical splits into one system. And there we focus a lot on server-side routing, or edge-side routing, I don't make a big distinction between those two.
Each of those systems delivers its own frontend, its entire stack from the database to frontend, and we integrate those systems with things that we already mentioned, like transclusions or also components in the other system, both transclusions with ESI or also client-side transclusions that you just mentioned. And also simple things like links between those two systems, right? So they are really independently deployable. They are manageable by one team. Why would you put that into your frame of reference?
Luca Mezzalira: In that case, I would say are we in front of micro-frontends? Because the reality is, yes, you divide by system, but if we say that everything that is divided by multiple systems renders on the client-side might represent micro-frontend, then where is the distinction between a single-page application or micro-frontends, whatever it is? So I think the distinction on micro-frontends is the fact that you have a map with a business domain, and then you can go more granular. The fact that you have an application shell that I think is one key distinction for micro-frontends and other implementations. In your case, you are dividing more in a modular monolith fashion, where you divide some verticals that might or not represent a domain, and then you are basically linking and using web standards for moving through between the shoes. I think I'm not even sure that I would categorize it as micro-frontends.
Lucas Dohmen: That's good to know because I just wanted to understand where you see the distinction. Because in the past, I saw descriptions of micro-frontends where this would be part of it and other parts where this would not be part of it. So it's always good to get a good frame of reference. Because it's a different approach to it that solves some of the same problems because you still can deploy independently and so on. That helps me a lot. Okay, so one thing that you also described in your book is the whole topic of the back-end structure.How is the back end structured to allow access from the frontend? You outline three ways, API gateways, BFFs, and service dictionaries. Can you just give us a brief overview of those three approaches and where you see them fit?
Luca Mezzalira: Sure, I will start with the service dictionary that probably is nothing new, but I think is very helpful. So a way that I found helpful to decouple micro-frontends from the endpoints that allow basically to run independently, the back-end parts with the front-end part, is injecting basically to the micro-frontends the list of endpoints to use with a dictionary, basically, of services that are available. That allows a micro-frontend to pick the service that they need. And also, potentially, you can do something even smarter. And every time the micro-frontend is questing a specific service dictionary, you serve a list of endpoints that are useful for that version of the micro-frontends.
That allows, for instance, if you work with API control first, where you maintain the same code and at the same contract between the API, then you can evolve the application independently. You don't even have to care about injecting them in CI/CD, as I've seen before, or even create a library that is loading inside of micro-frontends for handling this part. Because when you have these kinds of information that are loaded, instead of having all the micro-frontends using a specific version of the APIs, you might wish that you have some of the micro-frontends using a version, some others another version, and then you need to coordinate the redeployment of these shared libraries that is a pain, especially in large organizations. So this one is just a runtime way for handling something as simple as a JSON Schema or a JSON that is providing a list of endpoints that are specific for a micro-frontend.
API gateway is a well-known way of exposing APIs, especially in the microservices world. And in that case, you have your endpoints behind that API gateway wherever you want, a portion of a monolith, and the rest of microservices or microservices completely, up to you. But for the client, it's not a big deal. And that basically also might help where people are saying, "Oh, if we work with microservices and micro-frontend, we need to have cross-functional teams." It's not true. At the end of the day, you can use APIs as a nice way for communicating between teams, front and back end, and maintain the independence of these two layers. Then there are people that argue, but I want to have some work that is handled by one team only, can deliver a feature independently, and create value for the customers.
And I agree, that is the favorite way also for me. But there are certain situations where you cannot do that. For instance, in my previous company, we had roughly 40 different targets on the frontend we needed to manage and with different technologies. So if I have to create a team that can deliver a future end-to-end without creating first-class citizenship inside my teams, I need to have a team of 15, 20 people. That is not manageable at all, it doesn't perform. So instead, if we divide, in that case, front and back end, you can have, let's say, more interaction between front-end and back-end teams. But in the end, if you work well with the API contract first, you reduce basically this type of interaction that can work independently against the same API contract that is not changing every day.
And the last one is backend for frontend, where backend for frontend is a pattern that usually allows a front-end team to create a layer that is in between the APIs and the frontend. And they are able to use the APIs that they want, put them together and serve to their client. Usually they are divided by device. So you maybe have a mobile backend for frontend, one web, etc. But I have seen also people that are dividing per domain. So instead of having one per device, you have one for, I don't know, the catalog, and one for authentication. And you handle it in that way.
It really depends on how complex the application is, how large is the application of your structure. But backend for frontend provides a benefit where also if someone is updating, let's say, an API and you're not aware of that, for any given reason, is not going to cause a cascade effect on the client-side. So you can slowly but steadily migrate your API on the backend for the frontend layer and also aggregate them in a way that the client can do less round trips and provide a better experience for the users. And sometimes I have seen use REST, sometimes I've seen use GraphQL for this implementation. It's completely up to the team. And often, I have also seen one backend for frontend written with GraphQL and using Schema Federation for stitching together the different APIs in a unique layer that the clients can consume either mobile, web, micro-frontend or monolithic application.
Who is responsible for BFF?
Lucas Dohmen: Where do you see the responsibility for the BFF? Is it the responsibility of the front-end team that uses it? Or is it the responsibility of a different team?
Luca Mezzalira: For me, it would be the responsibility of the front-end team. Because they are the ones that are using that layer and consuming that layer. So they need to know how to handle that. But I would recommend having some help from the back-end teams because there are certain, let's say, topics like scalability, observability, stuff like that, that they have definitely more experience with, especially when we are talking about building microservices.
Lucas Dohmen: Very cool. So one thing you already brought up, but I wanted to have as our last topic for the day is the question of feature teams with component teams. So how do you see team structure and where do you see it in regards to all the things that we talked about until this point?
Luca Mezzalira: I don't have a strong preference. I mean, I work in both and I've seen both systems working. I think that the context should drive that decision. As I said before, I had the possibility to work in companies where it was impossible to work with features teams, and others that I worked in features teams and it was working extremely well. The problem there is when you have a limited amount of resources, but the number of features is growing. And then you have a feature team that suddenly became a features team. And therefore, you have to handle multiple events that are touching multiple points and the complexity starts to rise.
For me, it's very important as a tech leadership, in general, architects, principal engineers, whatever, that we take regular steps back to understand if our model is still valid. Because often, companies start in one way and they stick with that despite it not working. And then the problem is, “Oh, but we don't have enough developers”, or “We don't hire the right developers”. And in reality, maybe the problem is only how the communication structure works, how the company is organized.
So either that should be a component of the feature team, my suggestion is to check regularly if that is the model that is still working for your company or if the way how you sliced your domains is correct. Because as the company's evolving, your architecture has to evolve with the company. It's not something static. It's completely fluid and organic. We need to bear in mind that the moment that we are designing an application today, in one year's time, the things could be completely different with the same people or not. Because the business drifts towards a different direction from the beginning.
So the assumptions and the characteristics of our architecture and organizational structure that we made a year ago, are now obsolete and we need to replace them with another way. So don't be afraid to change and switch models if you see that there are some challenges. And question yourself, it might be that you create a genuine discussion, but questioning the decision that we were making, like, 6 months ago, or 4 months usually is a good time, but 6 to 12 months ago is definitely one thing that I encourage any company to do.
Lucas Dohmen: I think those are very good closing words because I think it's very true for a lot of parts of our system. We should question our decisions and also think about which architecture really fits our needs. And maybe at the beginning where we are more flexible of changing things, especially changing things up when we notice that it doesn't fit us even though we thought that it would. So thank you so much, Luca, for your time and for your insights. And I wish you a nice day and all our readers the same.
Luca Mezzalira: Thank you very much for having me. It was a pleasure sharing my perception of micro-frontends with you. I hope that you will enjoy the book.
Lucas Dohmen: Bye.
Luca Mezzalira: And thank you again for having me.