5 years of OpenComponents

Matteo Figus
7 min readJun 13, 2018

--

OpenComponents (aka OC) was conceived around 5 years ago when at OpenTable we needed a better way to internally contribute to our consumer site’s codebase. After dedicating a good amount of my five years on OC and micro-frontends, I decided to share some of the most significant learnings.

1) That serverless thing 👍

One of the OC’s core features is to enable developers to publish and distribute production-ready components in under 10 seconds. During publishing, OC compiles and stores a JavaScript function to be executed by Node.js on the server on demand. Every component’s request results in an asynchronous execution of the closure that produces a view-model which is then used as data for the component to be rendered.

export const data = (context, callback) => {
const { name } = context.params;
callback(null, { welcome: `Hello ${name}`});
};

OC internally handles this mechanism similar to a “function as a service” for allowing teams to consistently and safely release components to production without the hassle of spending time on configuration and scalability. This turned out to be the core of “serverless” architectures: brought to popularity by Amazon with Lambda around 3 years ago, the future for serverless architectures looks very bright.

2) Components as endpoints 👍

Another idea is a run-time composition of front-end fragments as opposed to a build-time composition (the more generalist approach of bundling a whole app with shared unique CSS and JS bundles). In practice, the goal is to use micro-services for the front-end with continuous delivery in mind, in order to provide autonomy to teams in mid-to-large organisations.

Shared ownership of a page at OpenTable.com, with multiple teams autonomously owning various parts with independent development, testing, and deployment

I have to admit this is still contentious from a theoretical point of view, but from a practical point of view we achieved our goal with great results in terms of robustness, resiliency and performance. Today this is a quite popular trend and it even has a name: micro-frontends.

3) Scoped CSS and CSS-in-JS 👍

I remember that three years ago when talking about OC in conferences and public events, people were not sure about the idea of inlining a component’s CSS inside a <style> tag or using JavaScript to do that. In fact, many thought it was crazy and wrong in so many ways.

One of the things we tried originally was to use a shared CSS layer (from an existing Sass project that would export a whole bundle structured with an agreed naming convention) for all the front-end, and ship components “unstyled”. Here’s how the markup would have looked like when doing a server-side request on a page:

<html>
<head>
<link href="//cdn.com/bundle.min.css" />
</head>
<body>
<oc-component href="//oc-registry.com/header/1.x.x">
<div class="header-site">
Server-side rendered header component
</div>
</oc-component>
<oc-component href="//oc-registry.com/advert/1.x.x">
</oc-component>
...
</body>
</html>

Unfortunately this approach had some issues, one in particular: there was an hard dependency between each component and the shared CSS layer. As a consequence, there was a hard dependency between each component maintainer and the shared CSS Sass project maintainers. This was pretty much against OC’s philosophy around continuous deployments and autonomous teams.

CSS-in-JS was exactly what we needed. When each component started having its own style together with all the server and browser JavaScript (together with techniques to optimise and encapsulate), the dependencies between styles (and the dependencies between teams) were gone. Developing, testing and deploying was just easier and simpler to do. Today CSS-in-JS is a de facto standard for micro-frontends and the tools are just fantastic.

4) Multiple HTTP connections and HTTP/2 🤓

A contentious part on having runtime composition is that fragments are not just simple HTML snippets. When composing on runtime 10 fragments, each with a <script> tag that will make a HTTP request, performance could be affected because the browser will need to make many requests to the CDN to fetch all the resources for the page to be rendered. Luckily HTTP/2 and multiplexing make that easier. There may be fewer opportunities for compression, but in my experience, this is often an acceptable compromise.

5) External adoption 😍

A problem of something like OC is that it’s not for everybody: when we open-sourced the codebase and released the whole product under MIT for 100% free usage and modification, we knew that small-to-medium organisations are very likely not in need of something like that. On the other hand, medium-to-big organisations very often either prefer developing something like OC in-house or they are reluctant to trust an open-source framework that is externally developed and maintained.

But we were wrong.

A couple of years later, new adopters like Skyscanner, Chegg, Cisco and more started to get in touch with us, adopt OC in production, and contribute back to the community by creating new issues, proposing new ideas, and submitting code changes.
I am very proud of some of the stories many contributors shared here.

6) External evangelism 😎

Many developers including Nick, Mattia, Ant, Maria, Dev, Genar, and myself had the chance to talk about OC and micro-frontends in more than 30 events around the globe, gathering feedback and meeting some of the greatest community experts to discuss technical and cultural challenges around this architecture. This allowed us to design the system having in mind not only a specific scenario as a use-case, but constantly challenging our assumptions in order to be able to tell the story to someone that had very little context. When you work on a codebase for years and you need to present it to an audience of strangers in 25 minutes, you need to keep the story simple, and the best way to do it is to keep your system simple, modular and well documented.

7) External contributions 😎

In my experience, the best way to keep a system simple is to invest in code quality and have a very clear mission. It took a while to consolidate the what and the how, but the why was super clear from the very beginning:

“OpenComponents is an open-source framework that allows fast-moving teams to easily build and deploy front-end components. It abstracts away complicated infrastructure and leaves developers with very simple, but powerful building blocks that handle scale transparently.”

When we started to receive external contributions and feature requests, it was easy to decide how to proceed and prioritise work. Anything that was technically in line with the vision was something that we allocated time to review and merge. For instance, a group of developers helped to extend the Rest API in order to develop a dedicated Node.js client that handles caching and invalidation slightly differently than OC’s official clients. In theory we could consider this aspect a diversion and perhaps time wasted, but in practice opening up to new ideas resulted in an increase of external contributions we all benefited from.

8) Governance and community 🤗

One of the investments we made last year was to move the whole platform including core, libraries, plugins and tools to a completely new Github open org: https://github.com/opencomponents. This allowed us to safely move away from the boundaries of the internal organisation and expand our contributors’ range. The way it works is simple: if you have a repository around OC, we help you move it in and we don’t get in your way as long as the code and contributors adhere to our Code of Conduct. If you make any Pull Request it means you care, and you become a repo admin as soon as it gets merged. In this way, everybody is trusted to keep things aligned with the vision and possibly make enough mistakes and introduce innovation by learning with others.

One of the parts I’m quite proud of is the storage adapters: we worked together to abstract all the dependencies around AWS so that external contributors created and now maintain adapters for Google Cloud Platform, Azure, and more. This obviously facilitates adoption and contributions. (Big shout out to Nick, Ken Crawford and Piotr for making this happen.)

One important learning is that contributions could happen in many forms. Code contributions are of course much appreciated, but often feature requests, criticisms and questions bring much value to the project’s success.

9) Keep up with the community 😢

Blogging about OC is something we need to do more. The last blog post about OC was written by me over 2 years ago, which is a long time ago. We hope to improve that by writing small frequent articles in the future.

Another thing that revealed to be quite challenging was dedicating enough time to help all the users that reached out on our gitter channel. I think we are doing great, but I would love for us to figure out how to improve this a bit more. We are currently reorganising the whole documentation so that hopefully it becomes more and more self-serving.

Conclusion

I think it’s great to work on a project that has such a great impact. I also learned so much by connecting with so many people and hearing so many different stories during these years.

In the future, when working on a similar project, OC will definitely influence my decision making. These are some of the most important takeaways for me after hundreds of mistakes:

  • Open up the codebase from day 0
  • Be open about architecture decisions, processes, documentation, conversations. Make everything publicly accessible
  • Be inclusive and work hard to create a diverse group of contributors
  • Be organised and keep track of all the issues and progress
  • Automate everything you can — and invest in keeping automation working
  • Welcome feedback and criticism all the time
  • Ask for help when you need it
  • Take some risks when designing your software but don’t go too far — pay your technical debt and learn from your mistakes
  • When working on developer tools, use your own tools often in order to have a short feedback loop and improve empathy
  • Keep making mistakes and don’t be afraid to show it — being human is totally fine and awesome

--

--

Matteo Figus

A creative technologist with 13y+ professional experience on writing software, leading teams and delivering value. Currently working @ AWS. Opinions my own