Brussels / 4 & 5 February 2023


The problems you will have when creating a plugins system for your shiny UI project

When creating a plugin system for a UI project, some of the questions one will undoubtedly have to answer are: What should we allow to be extended? What should the lifecycle of plugins be? How can developers test and distribute plugins?

In this presentation we will share the issues and questions we faced when developing a plugin system for Headlamp, a Kubernetes UI project, and how we addressed them.

UIs and their effectiveness can be very subjective. What works for some users will very likely not please many others.

In Open Source, a full adaptation of a project to one's needs can be achieved by forking and modifying a project but that often results a massive effort to keep the fork or downstream changes close to upstream.

An alternative to maintaining a fork can be a comprehensive plugin system. Such systems allow a project’s functionality to be extended via code that's dynamically loaded. Such extensions or plugins allow developers to isolate their changes and focus on them, thus avoiding having to fork and modifying the original project (or keeping changes to a minimum), and it becomes the base project maintainers' responsibility to keep the plugins working.

JavaScript is a very flexible language to accomplish such extensions in a project by dynamically loading code, and React allows to reuse components in an isolated way, but developing a plugins system comes with many decisions and implications: What should we allow to be extended (and how)? When should we load plugins? What if they fail to load? What about the lifetime of plugins’ React components? How to avoid bundling modules that will be available in the base project when plugins are loaded? How should end users run the plugins? How can they test the plugins?

We had to figure out all these questions when developing Headlamp, a Kubernetes UI that can be run as a web or desktop app and was created to offer a generic UI in its core but allowing users to modify and brand it through plugins, instead of having to maintain a fork of it.

In this presentation we will share how we addressed the questions around creating a plugin system: how we used webpack’s external modules to avoid bundling core modules, how we first shipped only type definitions of the libraries plugins use (and later decided we needed to ship the source code itself), how we created a helper script to bootstrap and keep updates under control, and many other considerations. Hopefully this will help early-stage projects keep these implications and possible solutions in mind when developing their own extension points. We’d also like to get others’ perspectives and comments on what we could have done differently, in the Q&A session.


Joaquim Rocha