Extensibility and Customization Mechanism Definitions

This is a(n imperfect) glossary for various customization and extensibility mechanisms in the Open edX Platform. In the short term, this document is linked from an Extensibility and Customization Survey I (David Joy) am doing ahead of my talk on the subject at the 2023 Open edX Conference.


Django Settings

Django Settings are the most fundamental way of configuring the Open edX Platform and customizing it to your environment.

Micro-frontend Environment Variables

Micro-frontends are configured via a set of environment variables that are baked into the MFE at build time. They can also be overridden via API at runtime using the MFE config API.


Backend Translations

This is the server-side (and legacy frontend) way of doing i18n and localizations in the Open edX Platform. It uses the Django translation libraries and .po files checked into the backend service’s repository.


Micro-frontend Translations

This is the client-side way of doing i18n and localizations in the Open edX Platform’s micro-frontends. It uses react-intl to consume .json files full of translations.

APIs and Events

Event Bus

The “event bus” allows for decoupled, event-based communication between micro-services. Event hooks from the Hooks Extension Framework may be broadcast onto the event bus.

Hooks Extension Framework

The Hooks Extension Framework allows new apps within edx-platform to ‘hook into’ existing data flows elsewhere in the platform without directly referencing the source of the data by subscribing to existing “events” and adding “filters” to existing processes. This allows new apps to stay decoupled from existing systems without the need for developers to fork the code.


  • Open edX Hooks Extension Framework docs:



The Open edX Platform has a variety of REST APIs available to be used with new applications and frontends.

Theming and Branding

Comprehensive Theming

Comprehensive Theming is a mechanism by which you can overlay or override elements of a legacy frontend (i.e., not a micro-frontend) by creating a “theme” that mirrors the file structure of the application’s default UI elements (JavaScript, SASS/CSS, Django templates, etc.)

Micro-frontend Branding

Micro-frontends have a branding mechanism that allows operators to override the default SASS files and logos of a micro-frontend by creating their own copy of the brand-openedx package.


Custom in-course JavaScript Apps

Allows course authors to embed custom JavaScript apps into their courses. (Also called custom JavaScript problems or JS Input problems)


Learning Tool Interoperability is a standard that allows the Open edX Platform to load third party tools into our courses and interfaces. It generally uses iframes to accomplish this.


XBlocks are a fundamental part of the structure of an Open edX course. Many are built into the platform, but creating new XBlocks allows course authors to express learning materials in unique and innovative ways.

Micro-frontend header/footer overrides

Micro-frontends allow developers to override their headers and footers by creating an “alias” at build time in the micro-frontend’s package.json file. Replacement headers/footers are React components and must satisfy the default component’s expected set of properties.

  • (Documentation for this forthcoming, it was lost in the ReadTheDocs → docs.openedx.org transition.)


Django App Plugins

Django app plugins allow extension by automatically adding PIP-installed django apps to the application’s INSTALLED_APPS list. It also allows the app’s settings, URLs, and signals to be recognized by the Django project.


  • edx-django-utils/plugins:

  • Django App cookie cutter:


Creating an independently deployed micro-service to add functionality to the platform. A service like this would generally use APIs or Events to communicate with other parts of the platform.

  • IDA cookie cutter:


Making a git “fork” of one of the Open edX Platform’s repositories to arbitrarily change code in it. The customization of last resort. Note, making forks to do work you intend to merge upstream is a perfectly valid workflow; this isn’t talking about that, but rather, using forking to make modifications you have no intention of being able to merge upstream.