A worked example of every major Open edX plugin interface, built around a small "course archiving" feature you can run end-to-end. Use this repo as a reference when building your own Open edX plugin.
This is a monorepo of four sub-packages, each demonstrating one extension point:
| Sub-package | Plugin type | What it does |
|---|---|---|
backend-plugin-sample/ |
Django app plugin | Adds a CourseArchiveStatus model with a REST API, an Open edX Events handler, and an Open edX Filters pipeline step |
frontend-plugin-sample/ |
MFE plugin slot widget | Replaces the learner-dashboard course list with one that lets learners archive courses |
brand-sample/ |
Paragon brand package | An autumn-inspired color palette |
tutor-contrib-sample/ |
Tutor plugin | Installs and wires up the three above for a Tutor-based deployment |
Requires Tutor >= 20 with tutor-mfe, and an Open edX environment that supports design tokens (Paragon >= 23, "Teak" release or later).
The tutor-contrib-sample plugin in this repo installs the published backend, frontend, and brand packages and wires them into Tutor:
pip install -e ./tutor-contrib-sample
tutor plugins enable sample
tutor dev launchThis is enough to see everything working: visit the learner dashboard and you should see the customized course list rendered with the brand applied. See tutor-contrib-sample/README.md for what each piece of the plugin does.
To edit code in this repo and have your changes apply inside Tutor:
-
Backend —
tutor-contrib-sampleregistersbackend-plugin-sampleas a mounted directory, so a single command before launch is enough:tutor mounts add "$PWD/backend-plugin-sample" tutor dev launch -
Frontend — bind-mount a local MFE checkout into
tutor-mfe, then point its webpack at your localfrontend-plugin-samplecheckout. Seefrontend-plugin-sample/README.md. -
Brand — use tutor-contrib-paragon to recompile and serve the brand from disk. See
brand-sample/README.md.
This path assumes you already have edx-platform running locally (bare-metal or devstack-style venv) and at least one MFE checked out.
-
Backend — install editable into the edx-platform Python environment and migrate:
pip install -e ./backend-plugin-sample python manage.py lms migrate openedx_plugin_sample python manage.py cms migrate openedx_plugin_sample
-
Frontend — in your MFE checkout, add the
module.config.jsandenv.config.jsxshown infrontend-plugin-sample/README.md, thennpm ci && npm start. -
Brand — set
PARAGON_THEME_URLS.variants.light.urls.brandOverridein your MFE'senv.config.js[x](ortheme.variants.light.urlin a frontend-basesite.config.tsx) tohttps://cdn.jsdelivr.net/gh/openedx/sample-plugin@main/brand-sample/dist/light.min.css. Seebrand-sample/README.mdfor the full snippet.TODO: a fully local brand-development flow without Tutor (recompile + serve from disk) is not yet documented.
- Open edX community Slack and discussion forums
- Issues with this sample specifically: openedx/sample-plugin issues