Micro Frontend base plugin for Tutor

This plugin makes it possible to easily add micro frontend (MFE) applications on top of an Open edX platform that runs with Tutor. To learn more about MFEs, please check the official Open edX documentation.

In addition, this plugin comes with a few MFEs which are enabled by default:

Instructions for using each of these MFEs are given below.


pip install tutor-mfe


To enable this plugin, run:

tutor plugins enable mfe
tutor local launch

When running the plugin in production, it is recommended that you set up a catch-all CNAME for subdomains at the DNS provider: see the Configuring DNS Records section in the Tutor documentation for more details. This way, the plugin will work out of the box with no additional configuration. Which is to say, if your LMS_HOST is set to myopenedx.com the MFEs this plugin provides will be accessible under apps.myopenedx.com by default.

To check what the current value of MFE_HOST is actually set to, run the following:

tutor config printvalue MFE_HOST
Account MFE screenshot

An MFE to manage account-specific information for every LMS user. Each user's account page is available at http(s)://{{ MFE_HOST }}/account. For instance, when running locally: https://apps.local.overhang.io/account.

Gradebook MFE screenshot

This instructor-only MFE is for viewing individual and aggregated grade results for a course. To access this MFE, go to a course 🡒 🡒 Instructor tab 🡒 Student Admin 🡒 View gradebook. The URL should be: http(s)://{{ MFE_HOST }}/gradebook/{{ course ID }}. When running locally, the gradebook of the demo course is available at: http://apps.local.overhang.io/gradebook/course-v1:edX+DemoX+Demo_Course

Learning MFE screenshot

The Learning MFE replaces the former courseware, which is the core part of the LMS where students follow courses.

Profile MFE screenshot

Edit and display user-specific profile information. The profile page of every user is visible at http(s)://{{ MFE_HOST }}/profile/u/{{ username }}. For instance, when running locally, the profile page of the "admin" user is: http://apps.local.overhang.io/profile/u/admin.

Course Authoring
Course Authoring MFE screenshot

This MFE is meant for course authors and maintainers. For a given course, it exposes a "Pages & Resources" menu in Studio where one can enable or disable a variety of features, including, for example, the Wiki and Discussions. Optionally, it allows authors to replace the legacy HTML, Video, and Problem authoring tools with experimental React-based versions, as well as exposing a new proctoring interface that can be enabled if the edx-exams service is available.

Discussions MFE screenshot

The Discussions MFE updates the previous discussions UI with a new look and better features.

Authn MFE screenshot

This is a micro-frontend application responsible for the login, registration and password reset functionality.

MFE management

Adding new MFEs

Other Tutor plugin developers can take advantage of this plugin to deploy their own MFEs. To declare a new MFE, a new configuration setting should be created with the "_MFE_APP" suffix. This configuration setting should include the name, git repository (and optionally: git branch) and development port. For example:

config = {
    "defaults": {
        "MYMFE_MFE_APP": {
            "name": "mymfe",
            "repository": "https://github.com/myorg/mymfe",
            "port": 2001,
            "version": "me/my-custom-branch", # optional

The MFE assets will then be bundled in the "mfe" Docker image whenever it is rebuilt with tutor images build mfe. Assets will be served at http(s)://{{ MFE_HOST }}/{{ MYMFE_MFE_APP["name"] }}. Developers are free to add extra template patches to their plugins, as usual: for instance LMS setting patches to make sure that the LMS correctly connects to the MFEs.

Disabling individual MFEs

To disable an existing MFE, set its corresponding configuration setting to "null". For instance, to disable the MFEs that ship with this plugin:

tutor config save --set MFE_ACCOUNT_MFE_APP=null
tutor config save --set MFE_GRADEBOOK_MFE_APP=null
tutor config save --set MFE_PROFILE_MFE_APP=null
tutor config save --set MFE_COURSE_AUTHORING_MFE_APP=null
tutor config save --set MFE_DISCUSSIONS_MFE_APP=null
tutor config save --set MFE_AUTHN_MFE_APP=null
Adding custom translations to your MFEs

This plugin makes it possible to change existing and add new translation strings to MFEs. Here is how to do it:

  1. Identify the ID of the string you would like to translate. For instance, the ID of the "Account Information" string in the account MFE is "account.settings.section.account.information" (see source).

  2. Create a folder and i18n file corresponding to your MFE app and language in the Tutor root. This location of this file should be /path/to/tutor/env/plugins/mfe/build/mfe/i18n/<app name>/<language code>.json. For instance, to add French ("fr") translation strings to the account MFE, run:

    cd "$(tutor config printroot)/env/plugins/mfe/build/mfe/i18n/"
    mkdir account
    touch account/fr.json
  3. Add your entries to this file in JSON format, where the key is the string ID and the value is the actual string. For instance:

      "account.settings.section.account.information": "Information du compte"
  4. Rebuild the MFE image and restart the MFE with:

    tutor images build mfe
    tutor local start -d

Your custom translation strings should now appear in your app.

Customising MFEs

To change the MFEs logos from the default to your own logos, override the corresponding settings in the MFEs environment using patches openedx-lms-production-settings and openedx-lms-development-settings. For example, using the following plugin:

from tutor import hooks

MFE_CONFIG["LOGO_URL"] = "<URL>/logo.svg"
MFE_CONFIG["LOGO_TRADEMARK_URL"] = "<URL>/logo-trademark.svg"
MFE_CONFIG["LOGO_WHITE_URL"] = "<URL>/logo-white.svg"
MFE_CONFIG["FAVICON_URL"] = "<URL>/favicon.ico"
MFE_CONFIG["LOGO_URL"] = "<URL>/logo.svg"
MFE_CONFIG["LOGO_TRADEMARK_URL"] = "<URL>/logo-trademark.svg"
MFE_CONFIG["LOGO_WHITE_URL"] = "<URL>/logo-white.svg"
MFE_CONFIG["FAVICON_URL"] = "<URL>/favicon.ico"

To install custom components for the MFEs, such as the header and footer, override the components by adding a patch to mfe-dockerfile-post-npm-install in your plugin:

from tutor import hooks

# npm package
RUN npm install '@edx/frontend-component-header@npm:@edx/frontend-component-header-edx@latest'
# git repository
RUN npm install '@edx/frontend-component-footer@git+https://github.com/edx/frontend-component-footer-edx.git'

The same applies to installing a custom brand package:

RUN npm install '@edx/brand@git+https://github.com/edx/brand-edx.org.git'
Installing from a private npm registry

In case you need to install components from a private NPM registry, you can append the --registry option to your install statement or add a npm config set command to the plugin. In some cases, for example when using GitLab's NPM package registry, you might also need to provide a token for your registry, which can be done with an additional npm config set command as well:

from tutor import hooks

RUN npm config set @foo:registry https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/
RUN npm config set '//gitlab.example.com/api/v4/projects/<your_project_id>/packages/npm/:_authToken' '<your_token>'
RUN npm install '@edx/frontend-component-header@npm:@foo/<your_frontend_component_header_name>@latest'

MFE development

Tutor makes it possible to run any MFE in development mode. For instance, to run the "profile" MFE:

tutor dev start profile

Then, access http://apps.local.overhang.io:1995/profile/u/YOURUSERNAME

You can also bind-mount your own fork of an MFE. For example:

cd /path/to/frontend-app-profile
npm install  # Ensure NPM requirements are installed into your fork.
tutor dev start --mount=. profile

The changes you make to your fork will be automatically picked up and hot-reloaded by your development server.

This works for custom MFEs, as well. For example, if you added your own MFE named frontend-app-myapp, then you can bind-mount it like so:

cd /path/to/frontend-app-myapp
npm install
tutor dev start --mount=. myapp

However, if you try to bind-mount an unknown MFE, you will see a Docker Compose error such as:

ERROR: The Compose file is invalid because:
Service myapp has neither an image nor a build context specified. At least one must be provided.

Please note that bind-mounting a fork is only available for development (tutor dev ...), since production MFEs are compiled and served out of a single container. If you want to use a fork of an MFE in production, then you will need to set the repository URL in $(tutor config printroot)/config.yml:

    name: profile
    repository: "https://github.com/YOUR_FORK_ORGANIZATION/frontend-app-profile"
    port: 1995

and then rebuild the MFE container image with tutor images build mfe.


To disable this plugin run:

tutor plugins disable mfe

You will also have to manually remove a few settings:

# MFE account
tutor local run lms ./manage.py lms waffle_delete --flags account.redirect_to_microfrontend

# MFE profile
tutor local run lms ./manage.py lms waffle_delete --flags learner_profile.redirect_to_microfrontend
tutor local run lms ./manage.py lms waffle_delete --flags discussions.pages_and_resources_mfe
tutor local run lms ./manage.py lms waffle_delete --flags new_core_editors.use_new_text_editor
tutor local run lms ./manage.py lms waffle_delete --flags new_core_editors.use_new_video_editor
tutor local run lms ./manage.py lms waffle_delete --flags new_core_editors.use_new_problem_editor
tutor local run lms site-configuration unset ENABLE_PROFILE_MICROFRONTEND

# MFE discussions
tutor local run lms ./manage.py lms waffle_delete --flags discussions.enable_discussions_mfe
tutor local run lms ./manage.py lms waffle_delete --flags discussions.enable_learners_tab_in_discussions_mfe
tutor local run lms ./manage.py lms waffle_delete --flags discussions.enable_moderation_reason_codes
tutor local run lms ./manage.py lms waffle_delete --flags discussions.enable_reported_content_email_notifications
tutor local run lms ./manage.py lms waffle_delete --flags discussions.enable_learners_stats

Finally, restart the platform with:

tutor local launch


This Tutor plugin is maintained by Adolfo Brandes from tCRIL. Community support is available from the official Open edX forum. Do you need help with this plugin? See the troubleshooting section from the Tutor documentation.


This software is licensed under the terms of the AGPLv3.