Frontend Pluggability Summit

Over the last years we have been migrating our user experiences away from the server side, to micro-frontends based on the React framework. This has allowed us to iterate faster on user experiences and deliver value faster. However, our frontend stack doesn’t provide the same facilities that we have on the backend for extending and customizing the base platform installation. For example, on the backend we now have events and filters and Open edX plugins. Furthermore, XBlock has been available for customizing course content for many years.

I believe that the need for pluggability on the frontend has now become urgent. There have been a number of recent pull requests that have committed features that are specific to a particular user of the platform, rather than general and valuable to the entire community. And while other PRs have pushed the pluggability story forward, without architectural direction and community buy-in these tend to solve for a limited set of use cases, all the while adding to the burden of maintenance and documentation.

We need to be able to support customization of the platform frontends, in support of the needs of independent users, without altering the shared foundation. Unfortunately, we do not currently have a strong, agreed to proposal for moving forward.

Furthermore, I would argue that we need customization to be possible without forking repositories. Doing so is bad for the team forking and the community as contributing back becomes harder. At the very least, we need to minimize forking and enable easy upgrades. We want an approach that minimizes effort to port customizations into future releases.

I’d like to propose a Frontend Pluggability Summit to help us converge on a specific architectural approach to support user specific extension and customization of the Open edX platforms frontend views.

I propose that we do the following before, during and after the summit.

In advance, asynchronously:

  • Discuss and catalog the requirements for frontend pluggability in this thread
  • Capture any prior art either from the Open edX project or other platforms
  • Propose high level approaches and build teams around them to create a high level approach document. This is really like an asynchronous design hackathon, pitch an idea, build a team, produce an artifact.
  • Publish and review the proposed approaches

At the summit, synchronously:

  • Spend some time reviewing and discussing the requirements.
  • Review and discuss proposals that are on the table
  • Discuss the pros and cons of all approaches as a group over the course of several synchronous hours
  • Converge on a plan that will become an ADR or OEP documenting the approach
  • Develop a specific plan to deliver this capability where all stakeholders contribute to completing the work.

After the meeting, asynchronously:

  • Do the work to publish the architectural decision
  • Do a technical spike/POC to validate the selected technical approach
  • Groom the required work, determine who will do which parts, execute and ship it.

I have created a meeting poll to determine the time to meet that works best for interested parties. I am proposing a three hour meeting – with pre-work – so we can make as much progress as possible. Ideally, we would agree on the high-level approach during the workshop. In any event, we would conclude with an agreed set of next steps with owners for each.

There are some existing PRs that should be considered as part of the requirements for what we design and deliver. I’m including them here as a reference and start to the requirements gathering effort.

11 Likes

Thanks for organizing this. I completely agree that frontend pluggability is urgent.

FWIW: Last year, I needed to implement frontend plugins in another project of mine so I designed and developed a simple UI plugin framework for React, vaguely similar to the hooks framework in that the UI defines “Slots” which are customizable areas that contain “Widgets”. Plugins can then inject their own widgets into those slots or modify the default ones.

Designing and implementing the plugin framework was surprisingly easy, and it’s been working well ever since. I put the design details and code on my blog: Creating a UI Plugin Framework in React. If anyone has questions about what I learned from that experience, I’m happy to answer them. But the main point I’d like to make is that it doesn’t have to be complicated, and in my experience it can be done quickly and easily, even for relatively complex applications (I had to support white labelling, runtime config, plugin-defined URLs, theming via plugins, etc.).

In fact, if you end up with an approach like I took for that project, rolling it out at first is [almost] as simple as putting <DefaultUiSlot> ... </DefaultUiSlot> around the major elements of your user interface. Ta-da, it’s customization-ready.

Another well-known approach to UI plugins is Swizzling, used by Docusaurus themes to customize their React UI. It has some overlap with my approach, but some major differences. The ways in which you can modify components are more limited, but you can modify virtually any component without having to declare it as a “slot”. (In my case I had an explicit design goal to not support that, and only allow plugins to modify explicit slots, to improve long-term maintainability.)

2 Likes

This sounds like a great idea, Ed.

I’ll add that another existing PR that was started by @djoy and that I’m working to finish is for enabling a React-based iFrame plugin that lives in openedx/frontend-platform.

In terms of its abilities, it allows for:

  • Customizable window width/height of plugin slot
  • Multiple child MFEs can live inside a single plugin slot
  • Designed for future plugin types (LTI, Build-time, Module Federation) to be rendered based on the child MFE’s configuration. Linked is where the iFrame case exists and where the other types implementation logic would exist.

As for the PR, what’s left is:

  • Determine the desired fallback for when a plugin fails to render ADR
  • Write a test that ensures the desired fallback works correctly
2 Likes

That’s an excellent initiative to host a Frontend Pluggability Summit. The topic is timely and critical for the Open edX community.

At Raccoon Gang, we’ve been dealing with the challenges of frontend customization for some time. As a service provider for Open edX, we often need to customize the platform to meet the unique business needs of our clients. These customizations often extend beyond simply adding new features, they involve modifying existing features and components to align with specific business requirements. Also, one of the key considerations for us is maintaining the system’s upgradeability, we want to be able to easily transfer and apply platform customizations to the newer named releases, as they are ready. The current approach, which involves forking and customizing micro-frontends, makes this incredibly challenging.

We are currently exploring the use of NPM overrides and additional Webpack scripting. These could be integrated into the frontend-build repository without necessitating the forking of other frontend-app-* repositories.

Last month, we initiated an internal discovery with the following objectives:

  • Identify methods to override JavaScript code in Micro-Frontends (MFEs) with minimal changes, possibly by leveraging existing solutions in frontend-build or frontend-platform repositories.
  • Use a single repository to manage all code overrides and new customizations across MFEs.
  • Our customizations should be compatible with the latest MFE versions with minimal adjustments required.
  • Share a working example or even a fully implemented solution, specifically tailored for the Palm release MFEs.

We’ve developed a Proof of Concept (POC) using Webpack’s NormalModuleReplacementPlugin to replace entire files (modules) at build time. You can find it here: mfe-overrides GitHub Repository. We’ve tested this on a live installation, and it’s functional. However, it’s still a work in progress and requires further refinement to serve as a comprehensive solution.

It would be incredibly valuable to discuss the various approaches currently employed within the community. Maybe it would be possible to co-develop a robust framework for extending and customizing Open edX micro-frontends.

1 Like

Thanks all for the great input. I’ve started to catalog some of the proposed directions in Confluence.

1 Like

The best day to meet seems to be October 25, 2023. However, we have one person on the west coast of North America and one person in Ukraine.

Do either @braden or @Glib_Glugovskiy have flexibility for an early or late meeting?

1:00pm - 4:00pm

4 votes

Adolfo, Braden MacDonald, George Babey, Jason Wesson

10:00am - 1:00pm

3 votes

Adolfo, George Babey, Glib

Yeah I can do 10am Eastern if necessary.