 Hello, everybody! Namaste. I work at OpenTable. I work in the developer experience team. We build tools infrastructure for the other engineers. Of course I love open source and node building tools and DevOps. You can follow me on Twitter. But before I'm going to start and talking about our use case and what we build and how we deliver micro frontends, I think it's like I want to explain you a little bit some background about OpenTable. So that you understand why what I'm explaining you today, it works well for us. It might not well work for everybody. So it's like it's always a very unique way when you talk about architecture and way that you deploy in your team work. So OpenTable is kind of like an old company in the digital age. It's like 20 years old this year. We are part of the Booking Golding groups. Booking.com, Kayak, Agoda, rental cars. We kind of like manage all the restaurant reservation part. We deal with 24 million restaurants reservation per month. We are about 300 engineers and 50 engineers work on the web part of our infrastructure. Also the engineer is also important to know that we have engineering offices scattered around the world. So our headquarters are in San Francisco. I, for example, work in the London office. We have offices in Australia and India, in South America and so on. And the other part is like we also handle millions of requests per minute on our frontend. So the frontends still have to perform and handle pretty heavy loads. The agenda, what I'm going to talk about to you, it's like first I want to start with the why. It's like why micro frontends, it's something that makes sense. What is the problem that we're trying to solve here? And then it's like what exactly does that mean in practice? Like behind the scene, what that looks like? And then how you can implement something like that in your company and specifically how we are doing it at OpenTable. And then I will try to not be too long. It's the last talk of the day and maybe leave some time for Q&A at the end. So if we start for why, an important question it's like this is like it's an African proverb and say if you want to go fast, go alone. If you want to go far, go together. There is something implicit here. It's like say maybe we go slower when we go together. And that's might be true. So it's like, you know, and this is like the main reason of micro frontend. It's like, how can we go faster together? And if we think about teams, team size, organization structure complexity, let's say on the axis, and we look about some kind of like classical architecture that you have to start with the monolith. It's like that's super fine. You're super fast if you're alone, if you have one team, because it's like very, very quick iterating loops, not much moving part. Then the first thing that happens like normally it's like back to front architecture. So you have a back end and a front end split. And then you can go to a microservices. Maybe you have like an aggregation layer in between and then you have your front end. Until that part, it's like it's interesting to note that your front end is still a monolithic application. Even if you have a microservices architecture in place, most of the case, it's like your front end application. It's kind of like a monolithic application. And that's it's where the idea of micro frontend come in. How can we do something similar to what we do with the back end with splitting everything into services for the front end? So how can we split into single independent deployable units, the front end? Ideally, we might want to have something like that where we have a bull vertical. Someone else was mentioning today in the various talk that's like, ideally, you want to have like a front to back single unit, where the team have end to end ownership of that feature. It's not just the number of the teams of the complexity. It's like the principle that's like are being brought to are the same that you have like in microservice. So it's like single responsibility, scalability. So you can scale the specific part of the front end differently. Autonomy. So it's like, how can you develop, test, and deploy that part of the front end completely independently from the other teams? And how maybe how can you use different technology? How can you use part of a front end using maybe a framework and a part using another one? And I think it's like the last two points are what I think it's like are way more important to front end. So it's like different technology, the front end, it's like it's evolving at that very, very fast pace. Everybody now maybe want to move to react or view and like, you know, in a couple of years from now will be the same, maybe it's worth to say a couple of years ago was the same to Angular. So it's like it's very hard when you have a lot and a big front end with a lot of team working to have a unified code base because you will never go and rewrite stuff. Because maybe there is no need for that. Also one thing that maybe I think it's like it's important to notice, it's like the destructure, the one that we saw before. The old structure, this is like are also very, very representative of what it's called as like as a Conway load. So it's like this tend to map very close to how the organization of your company looks like. And I will tell you why we came and we start in that way and why we arrived all in this structure. It's a very, very interesting process because it's like it starts from some pain and some urgency that developed around how the company was organized. So to summarize it's like the idea behind micro front end, it's like it's really to enable multiple teams to work together and help them to kind of like have an end-to-end ownership and be able to independent test, develop and deploy part of the features that are built. So you could have like a team that maybe it's a search, it just need to deploy the search box for example without having to worry about all the navigation, what's the putter looks like, what's about the header. They just need to be able to deploy that specific part of the front. While this makes sense, it's like in a broader term, what does mean in practice? So if we have like, let's say that we have three parts of our page, like just starting with a very, very simple example. This page could be like, let's say that we have a header, we have like page content with our stuff and we have a foot. And let's say that it's like this, we want to have three teams working on that independently without having to redeploy the full front end every time we do a change on the footer for example. Well, the first part will be to try to have some kind of way so that's like those are served by a service. So it's like, you know, the header will be come from a service that will serve the header, the page and the footer. So it's like didn't mean it's like they will be served at runtime and we don't have to need to worry about how we can pull. One problem with this approach, and this is like was how we started initially, we started experimenting with micro content almost four years ago. So it's like we've been doing that since quite a while. This is what we started off similar. It didn't exactly look like that, but like that's the idea. One of the problem with this is that you don't have any way to handle breaking changes because what if the header team deploy header that's actually going to break my page. So what do you want to also to have? It's to have a way for version. So it's like you want to make sure that's like the components that you get you can get to a specific version. You can even lock it to minor or major depending on the cases, but that's also something that it's very important when you're talking about runtime. So the difference here mainly it's like it's a switch of mindsets like normally when you build your front end you do everything gets like a build time and then you deploy those build front end that's like get served down to your to your clients. In this case it's like all those parts are consumed at the runtime and so it's like you need to be very careful of breaking changes. This can be solved technically can be solved in various ways because like one way for achieving this is the iframe. One could be using Ajax and it's like unloading those parts dynamically. The other is like it's software. For example there is server side includes or varnish of edge size includes there are various ways of software that allows this to be used. We build our own kind of software. It's an open source project. It's called Open Component and I'm going to tell you a little bit how it's composing this project. It's composite about a few tools, some platform that you can run as an infrastructure. It's a little bit complex as a thing but we go to all these things. The central part is what we call the registry. The registry it's like it's a runtime registry. It's in charge of like serving your components and also publishing your components. It's like a REST API for those components where each component has its own end points and each component has its own independent points and it's in charge of a few things. Then we have a CLI tool. The CLI tool is very important. It allows the developer to build bootstrap and scaffold very quickly some components. It's allowed to publish and to run a dev locally dev environment for the registry for working on it and also you can use it in API for automating all the release and stuff. Mainly we never publish through the CLI. All the assets like for your component, those get stored on a CDN. The CDN it's like can be anything. We rely on S3 but we have a system that's like permit we call storage adapter that we provide the one also for Google Cloud and you can build your own as pretty easy to build one. So mainly you can you can host the assets for your components whatever you want. The same it's like it's similar to the templating system. One problem when you run a registry for frontend components it's like that you don't want to be lucky in the technology that you're building your component for. Like maybe yesterday we were using JTAG, then Andalbars, then React. We can keep these evolved. So we have what we call a template system and that again can support any kind of framework you like. The template system consists of two packages. One is a compiler that is used by the CLI to package all your assets together and one is like it's a very very lightweight package that is used by the registry to kind of like be able to render this to work. So mainly you can incorporate in this component all your opinion how you would like the old different ends. Like for example we decided to use React lately. We are using CSS modules for handling this CSS. So like you can encapsulate all of these in your kind of like template and you can have multiple of them. You can even have different teams have their own kind of templates and they work together. So like the boot is and it's a new update. It's like and we will see after in a demo how that looks like. Then I forget one part. It's like the client's library. Here I just there are a couple of options but there are many more developed for open components. There is like one for Ruby and others. The idea it's like those are library that can interrupt with the registry and consume this component. So for example the very very simple one that I think it's like three is on the 10th. It's like this big JavaScript library. So it's like let's say that you want to do a client-side rendering. You need to have this little library loaded and this will allow you to kind of like handle all the different components and sort of create out how this will work. While you're doing something like maybe at a server level where you are going to assemble and do a UI composition, then you want to use one of the other libraries. For example PHP library or Node library. And this is like it's interesting because you can do caching also at a library level and you can also do batch requests like let's say that you need 20 components to assemble together in a page. You just do that in a single request. Another little things like maybe that I haven't mentioned it's like what are components? What are the components that you put on the right? But components like are just universal pieces of JavaScript. We try to stick on universal because that's like the default thing. So like when we build a template specifically we want these components to work on the server, on the client, so that we can do server-side render for all our pages. So like the registry handle both server-side and can default to client-side rendering for any component. Tell you a little bit like a little bit what happened. So you can understand how we put together this infrastructure. It's let's say that you click opentable.com slash San Francisco restaurants. The first thing that you will eat will eat our front door. Because like this is like it's just a load banter with like all the things you have that you need like discoveries as it is. And this is let's say okay it means that I'm looking for a microsite that's how we call it looking for the start. The matrix San Francisco and this is redirected internally in our infrastructure. If you're interested we run on Mesos the whole infrastructure to an instance of that start microsite and we pass in some fields around here. And this is like we say okay it will give it to the start microsite and that will send up that page. That's kind of like architecture where we have this very independent website. It's like because we started breaking the monolith a few years ago. And so like how we went we went into a way of life in Denver. So like we have a target, we have a search result page, we have a restaurant page. And so we created some very small team that built the front to back kind of like mini-website for that. And they were very independent and agile and very very fast in moving forward. And that allowed us to break the monolith pretty quick and pretty fast and out of that we also created microservices behind the scene. But that's at one problem. And the problem was like that all of those sites maybe had some shared talk. So for example think of a header, think of a pointer. It's like exactly the same. And doing for us like that where the team working on these shared components, it was like really really hard to do a PR because it's like we need to do a PR in multiple rips. And maybe it's like we were based in London, maybe some of the team were in San Francisco, we have to wait the day after to review the PR. So it's like also orchestrating how we were going to deploy that. It's like it was very, very hard because we were to manage different time zone orchestrate that. And that was really frustrated. So in the keynote this morning there was like this mention about how if you want to change a system, like if you want to change, you need urgency. And it's like this for us was like really urgent. It's like more than urgency, this was really paid. So it's like and that's where we started thinking about what now it's called microcontent. There's a pattern like how can we deliver to defend without having to wake up the team in San Francisco without having to synchronize with that. So mainly what will happen it's like that behind the scene this is very simplified. But behind the scene at the start, we do a call on our component registry and get the components and then set it down. We're slightly that grows a little bit out of control during the breaking of the monolith approach. And we ended up with 22 microsite and more. So it's like it's now it's we're thinking about how can we reduce that and go to something like you know more things to maintain. So this is like where we are moving forward. Like same similar things. But we are calling a specific cold site that we internally we call the Lego. And what we do we say, well, Lego, this is like a need a page start. And then it call all the components that need and the service. What we made we transform that page that needs a full site. It's like a bigger component. But that actually that's what was between. And so this is allowing us to experiment with, for example, canary releases. So like when we do a release, we slowly pass traffic to the new version because it's like this, we can pick the latest version, for example, of the page component, you see that in the fly. And then we serve maybe 10%. Then we check about regression in real time with, for example, JavaScript error, how conversion are going live. If nothing, there is no regression, then we move on and like maybe we serve more until we have a full at the time. So I want to give you a little demo so you can understand a little bit how it looks like a component, which are the parts, how it's working with them. Because of technical reason for internet, I'm not going to do install NPM packages here live on stage. So but if you want to do it, you can just do NPM, I call it double if you like, and say OC, OC is like component. So if you if you hear me saying OC during the call, it means that I'm referring to open So what what happened when you what you can do is like on when you have a CLI available, you can of course ask some some documentation, comments that are there, but you can use it to initialize your component. So for example, you say OC init, you say the name of the component that you want to initialize. And then you can pass a the name of the template that you're doing. The template is nothing else that a as you see, it will try to install the OC template via compiler. Because like there is this convention that each template in the compiler, this is what the CLI use to package your application. And it will just batch it from from the public NPM. So you can create your own template very easily and just publish on NPM. And then everybody can just do init with that template and it will stop all and have like a CLI working with that type of component. I think this is going to take a little bit while. But yes, so it's like mainly it is like the idea that we vote in the last two years, we've been working on this abstraction over the technology. And this is working really, really, really nicely. Also the idea that with the couple, a compiler from the other part of the template that it's the renderer allows us, for example, to keep evolving the compiler, for example, a page from people, oh, we want to do the assessment this way, maybe we want to package and organize the web back a little bit different. We can keep deploying that without having to alter what we deploy on the region, as long as it's not a great change for the range. And so we'll see, we'll tell you success, you create your first component and you have some comment that you can run to start. I did it and I think I have it here. So what you have in a component, here we created like another component, it's like, first of all, it's like it's a month. So if we look at the package JSON, it's big enough for everybody to read it, or should I do more? Okay. So we see this normal stuff, like we have a name, you can add a description, a version, then we have like a specific OC part where we configured the part related to the open component. There are a couple of things, one is like the file. So here we say that we have a data entry that's points for server.js. We will see why it's there, because that sounds weird. I think if you're now like, wow, we are doing a frontend, what is a server.js there? We will talk about it. And then you have a template and say, okay, this is the entry point for my, in this case, would be a react probably application. And then you need to say that it's also template react. It already I have, I don't depend and see the compiler that we say. And this is like it's similar if you have used create react up of other tools that try to have a very, very minimal configuration. If we need to update teams with new features, they can just update the react compiler and the application will automatically benefit from them. And then you have some parameters. So because on the registry, your component, when we publish, we will have an endpoint, you can also have query pattern to that endpoint. And that means that's like you can do, here we can specify some documentation, for example, you can say, okay, we have a name parameter, parameters that you can pass it. You have a default, you can pass in the description. And this is used for some server size validation. When we do that, we do that also. But I wanted to touch back, well, we can look at what's up. It's like a very, very simple react application. It just prints the name that we pass in and do some tests. It's nothing fancy. Then we have the CSS. Again, like very, very simple. But the point is like, why do we have a server.js in our frontend component? And I think this is like it's the unique part of our solution, our open component. Because one of the parts that still a problem is like frontend is always a dependency on the event. So like, no matter what you're doing, there will be always some change. Maybe you want to do some A, B test. What if you change some data that you have done? So to do that, then you need to go with your backend team or the services and you do a PR there, you need to work and create a change. It's not that autonomous anymore. So we thought about, well, why not using a serverless function? So like, these are like actually our serverless function. If I open it, you will see it's export function, the acceptance context, and then you will call a callback. So these are things. And in there, it's like you have access, for example, to the query parameter. This is very similar API to what's like lambda in AWS. And what happened? It's like, we will call this function. We will this because run on your private infrastructure, you can have easily access to all your private infrastructure because also, for example, on S3 or cloud, you can also mark it as private. So that file is not available publicly. And so you're safe to do stuff on your private infrastructure here and without having even to expose a single API and, for example, one thing that we do, we use GraphQL as aggregation layer. But we don't want to expose a GraphQL endpoint. So what we do at this point, we can kind of like just use this as a proxy. It's kind of like your API gates. The interesting part is like, whenever you are deploying, there is a matching version one one with API and the component. So it's like, let's say that I'm releasing a component version two where I change stuff in the server, the older consumer of the other component won't change. The version one will still use version one of its own API, because it's being bundled together and published on the registry together. So this is like it's the unique part of open component. So what we can do here, we can run, for example, a dev registry, so to see how it looks like. So the command is simple to dev and then where you want to run it. A look, you see, created a packages folder because it's like it's packaging this folder. This is what will be then published to the registry. When you're locally, maybe it's not optimized. So if we go to the localhost, this is like our registry endpoint. And so we see that we have like header endpoint and it's a version 1.0. What we will normally have, because now we just created, you will have a list of all the versions published. So you can change that version, look back, if you change something in the documentation and really see how it is, because it's like all the components are in use. Whenever it's published, it's like it's never break. Everybody can still consume that version. That's because it's a runtime system, you don't want great contracts. And so you see that's like we created some very basic documentation out of it, like the parameters name. This is like it's how the endpoint will look like. Of course, it's like this is like it's somewhere. So it's like we can also do something like that if you will return at the minor version, the latest minor version. And then this is like here, we have like a preview of the component. So we can also see the full component in preview mode. And so what you see that's like, let's say we do, like this point, we are changing the model that we are serving from our serverless function. And we see it's like in real time, like how this is reflected. What is happening on the preview pane that it's like client side branch. So it's like we are fetching the component, we are doing a call for the data. And then we are doing a client side branch. And if you just hit the endpoint of the component, the default will be a server-side rendering. So this is server-side rendering of that component automatically. And that's mean that's like everybody can compose tools in any part and all the components for server-side rendering. So I'll do you, let's say that we have this component and let's say that we publish. We cannot do that in the name of because the internet is very weak. But for doing publishing, mainly, as you say that I need to see dev, you will do see publish. You will need to have a URL for your registry and be able to have access to the publishing of registry. And that's the component with the data and available in the data. But how do we implement this in the website? They said, we are the component, we are the teams, we created this component. And although every team can add new components to the registry whenever they want, they don't need to ask anybody. They don't need to ask a server admin, infrastructure, operations, it's like they just create a new component, publish it and it's available to everybody. At that point, there is a contract that you need to establish for consumers. So let's say that you want to integrate your component in your website. What you're going to do for client-side rendering will be something very, very simple. We use custom tags, so you will use, say, okay, these are like OC components, the URL of the registry, the name of the component, again, the version. Let's say that we want to lock it to the version one and get all the latest minus of version one. And then we add the client-side library. And this is like, it's everything you need for having your component working. So what you see in the preview is exactly what happened in behind the scene. This is exactly this. What about server-side rendering? So for example, here we have like a node example. You require the client, you instantiate it. Some stuff that you can do when you instantiate it, you can also warm up specific components. So those will be cached automatically on instantiation on the client. But cache means that, for example, all the components will be automatically cached in memory there. So when it will ask for a rendering, the only thing that we will call will be the function. It will get to the data and it will do the server-side rendering at that part in time. It's like the F below, it's not on the right. Here it's like we are doing a client render component. We save which components we have and then we get back to render HTML. We can also pass an option with a render, adders, whatever we need to pass, we can pass. This is like as a single component. You have also the render component that is like the batch endpoint. So you can have multiple components. So the thing is like we started using this on websites. So it's like multiple parts of our web infrastructure at OpenCable. It's as open components. And the teams independently deploy part of the content. For example, the adder actually is up component and many of them. We have I think it's like over 100 components on the web. But the point is like we say, what we can reuse it for? So for example, this is an email. And if you think about an email, well, it's like it's a bunch of components. And that's how we are also using the registry. We have a team that actually is building components for all our transactional emails. And because of that, they can compose the email as much as they like. They can do A, B tests and they can do that like every time emails sent out, the template combined with fetching the email from the registry. The other more obvious way is for external widgets. So like, you know, now every restaurant is like by just adding that script to the website and it's have our widget. And that means that we can deploy in all those people websites where we don't know nothing about it. I also wanted to show a little bit about some tools that we have when we deal with it. So for example, we have a Chrome tool that you can see in the back what it allows it to show. It will see all the components that are running on the page. You can select it for each component. You can also choose all the versions. And when you click one, it will switch that version in your production side. So because it's like it will kind of like get this component and we render the client side in this side. And you can also pass all the properties that this component is affecting. So for example, here we are changing the translation to Japanese and you see that like it gets. Also you can switch to local. And this is like it's pretty amazing because what you can do when you switch to local mean you say, well, this component, I want it from a dev local registry in that you can have your production websites running. And then you just fetch that specific part of the front end from your local registry. And you can kind of like real life work on that. Wow, work on that in real life. So people are like often asking, who else is using Open Component Production? So of course, as we started, Sky Scanner uses old introduction, CSCO, Chegg, and other companies started to use this production. We're just giving some numbers. It's like the registry that my teams like handle for all the components infrastructure at OpenTable. It's kind of like serve about five billion components a month. And all the team that handle that infrastructure and plus the framework and everything and tools is a team of two. We are just two on that. So like it scales pretty well. And we never had like no major accident. It's like it works very well for that. So this is like I wanted to try to make it a little bit short. So maybe we can have a little bit of conversation and question about it. And thank you very well. Thank you very much for attending. How do you tackle CSCO's problem when it comes to all your micro front ends have to be like super responsive? Because I can share it between different websites, right? If I have a micro front end. Yes. So it's like, one is like, when you build your compiler in the template, there is where where you really want to do a lot of work to make sure that's like, you know, the team doesn't have to care about this bit, but we do CSS. It's like we do everything's like, you know, for making sure that we serve the most efficient application. For sharing stuff, we try to make sure that components are encapsulated as much as possible. Because as long as soon as you start to have a dependency on something else, then you have a problem. If you try to keep this as small for the moment it's working, the next challenges that we'll have to face is like, probably how can we optimize share dependency? That is like, it's an art problem. When you start creating these different components, how do you like share data between them? I click on this button, I have a different micro front end that starts to react now. Yes. Normally you do that through events. You do a lot of event event listeners, you add all these event listeners. Yes. So you create your event pass and then you fully get to that. So any examples of where is he's being used for mobile apps? Because we constantly look at serving the end users without having them to install the app again. They have one installed app and then we want to rapidly change our content. The challenge with the mobile app is being that they have downloaded it again and again. It's a monolithic app. So you mean using web views inside the... Exactly. Will this be a good... We never tried, so we never experienced that. I think it would be definitely interesting trying it out and maybe have a prototype. It would be interesting. I cannot tell you about it, but we never tried that. That's what I was kind of...