Open edX Branding and Theming Improvements

At OpenCraft we’ve been investigating improvements to the way theming works on Open edX with the aim of making it faster, easier to use, easier to maintain, and more flexible. A more detailed overview of our goals can be found here

One of the first things we’ve investigated is the way forward with creating a consistent theme across edx-platform and MFEs. The results of the initial investigation can be found here. As we do further

We would love feedback on this so do leave any comments on the PR here:.

We wanted to ensure that the theming system is forward-compatible, such that upgrading a theme from one release to another should be simple and straightforward. Furthermore, we want the ability to allow deep modifications while still ensuring that maintenance burden of upgrade costs are as low as possible.

Currently, our primary theming mechanism is the simple_theme role. It is a pretty straightforward system. The role takes a base theme (we have a skeleton theme for it here), and an arbitrary list of variable names and values. It sets up the base theme, and adds the variables as SASS variables to the theme.

This allows us to set up a base theme that support customisation via variables, and then use the role to provide those variables as part of deployment. OCIM our tool for managing Open edX deployments includes a UI that allows customising these variables, and redeploying those changes to a new instance.

We would like to extend the above approach to work with MFEs as well, since it would allow us to have a single theme configuration that applies across all UIs. With OEP-48 this with within reach.

We would love to get community feedback on this effort as it progresses. Our future goals involve creating an open source UI for light theme customisations, that provides quick previews and feedback, and automatically deploys the latest theme changes. Community feedback will be essential in determining how we further develop and prioritise the work here.

CC: @Felipe


We continue to explore new ways to theme the platform that would open opportunities for near real-time theming, simpler theming etc. There are two development on this front:

  1. Dynamically-loaded themes
    We tested a new mechanism called module federation, to separate the theme code from the rest of the MFE so it can be plugged in dynamically. This opens up the possibility of getting a list of themes from an API and applying one of them dynamically. A demo of that can be seen here:
    The aim here in the short term would be to have a centrally hosted theme that is used by all MFEs. So it is possible to rebuild and upload a new theme to a central place like S3, and it will automatically be available everywhere. An ADR for this can be seen here:
  2. Uniform theming across edx-platform and MFEs
    OpenCraft uses a system called simple theme (as described in the previous post). This system allows us to specify theme overrides via edx/confiuration ansible variables.
    We’ve done some work to also convert this to a branding package. It works as both an edx-platform theme and a branding package allowing it to be installed once on the server, and then used by all MFEs installed on the same server. They use the same variables for theming, so you can get the same theme applied to both edx-platform and MFEs
    It’s currently demonstrated here; using an deliberately obnoxious theme.
    Over time will refine this to improve consistency and reduce code duplication.

We’ve recently been doing discovery on a new MFE that will be used to configure the theme a few other parameters for a new open edX deployment. The aim is to have Open edX ship with an MFE that you can launch after setting up your site, and use it to configure the theme, the site name, etc.

You can see and comment on the discovery documents here:

We would love your feedback and input on this, and would love to hear what you’d like to see in such an MFE.


Hi Kshitij -

Question for you: how do you handle the situation where the SASS in an MFE uses SASS variables from Paragon/the brand? That’s the one thing I haven’t been able to figure out how to handle, as it requires the MFE to have access to the original SASS files from paragon/the brand during SASS compilation time.

This is a pretty common thing, especially around colors, i.e., $primary-500, $gray-700, etc.

There are a couple of answers I explored for that, but I don’t think there is any magic bullet here.

CSS-in-JS and CSS variables could both solve this, but they aren’t what we have right now.

We could rebuild just the custom scss for each MFE, but this increases complexity a lot, and slows down everything again. Each MFE that needs custom theming be a submodule of a “theme” MFE. This MFE would rebuild the theme, and output a common CSS and mfe-specific css for all MFEs.

I think the best solution, in the end, is to simply not use such variables in MFE code. Instead, for any variable that needs to be applied, use a Paragon/Bootstrap class that applies that variable. This should cover most cases.

If you have a case that isn’t covered, but is generic enough, I think it belongs in Paragon. If you have a very specific case, perhaps that code can be hoisted up to the theme? This is probably not a great idea, but I don’t think I’ve come across any cases for this either.

This will need changes to existing MFE code, and I’m definitely scoping some time to help with that.

I’ve done some discovery on how the theming MFE (described in the previous comment) can be wired together with everything to allow it to change the theme. You can see the document here:

The main idea here is that this would be process that would react to changed in the theme and run some process (which would differ based on the deployment method) that would update the theme across the platform.

CC: @djoy