# Open edX Platform: the LMS and Studio monolith behind self-hosted course delivery

> The openedx-platform repository holds the CMS (Studio) and LMS services at the centre of Open edX. It is a Django monolith with React micro-frontends, an AGPL-3.0 licence, and an install path the README itself calls not simple.

**openedx/openedx-platform** — The Open edX LMS & Studio, powering education sites around the world!

- Repository: https://github.com/openedx/openedx-platform
- Website: https://openedx.org
- Stars: 8,199 · Forks: 4,360
- Language: Python
- License: AGPL-3.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/openedx-openedx-platform

## Two services in one repository: Studio and the LMS

The README is explicit that this repository provides two services. CMS, the Content Management Service, powers Open edX Studio, described as the platform's learning content authoring environment. LMS, the Learning Management Service, delivers learning content. They share a codebase, a settings tree under common/ and a single manage.py, and you address them by subcommand: ./manage.py lms and ./manage.py cms.

That split is the whole reason the project exists in this form. Course authors work in Studio; learners consume courses in the LMS. Both need the same course model, the same XBlock rendering pipeline and the same user records, so they live together and share migrations rather than being two projects that synchronise over an API. The cost is that a checkout is large and a deployment carries both halves.

The audience follows from that. It is for institutions and platform teams that want to run their own course catalogue, not for someone who wants to embed a video player and a quiz into an existing site. The README's own framing is blunt: installing and running an Open edX instance is not simple, and it strongly recommends using a service provider to run the software for you.

## Modular monolith, IDAs and micro-frontends

The architecture described in the README is layered. At the highest level there is a modular monolith, some independently deployable applications (IDAs), and micro-frontends (MFEs) built on ReactJS. This repository hosts only the monolith in the middle. The IDAs and the MFEs live elsewhere, which matters when you plan an upgrade: the monolith version and the frontend versions are separate decisions.

The practical consequence is visible in the startup instructions. Running ./manage.py lms runserver 18000 and ./manage.py cms runserver 18010 gives you what the README calls a mostly-headless Open edX platform. To navigate the UI meaningfully you also need at least the Authoring MFE, the Learner Home MFE and the Learning MFE running separately. A working installation is therefore several processes, not one.

On the backend, the dependency list in pyproject.toml shows the shape of the monolith: Django, celery for asynchronous task execution, codejail-includes for sandboxed execution of untrusted code, and django-config-models for configuration with auditing. Celery is not incidental. Grading, enrolment and notification work in a large course run happens out of band, so a deployment without workers behaves differently from one with them.

## Installing openedx-platform with Tutor, then running it bare metal

The README does not present a single install path. For production it recommends Tutor, the community-supported Docker-based Open edX distribution, and points at the Site Ops home on docs.openedx.org for deployment detail. Tutor also has a development mode, which the README recommends for all Open edX developers who want to modify, test or extend the platform. Follow that route first unless you have a specific reason not to.

The bare-metal path is documented as advanced and mostly undocumented, and the README limits community support for it. It is described as advisable for developers seeking an adventure and experienced system administrators willing to take on Open edX configuration themselves. The system dependencies are Ubuntu 24.04, Python 3.12, MySQL 8.0, Mongo 7.x and Memcached, with the Node version pinned in .nvmrc.

Backend dependencies are installed with uv, and the README distinguishes the production and development groups:

```bash
uv sync --no-default-groups --group bundled
uv sync --group development --group ci
```

Some Python packages need system libraries first. The README names mysqlclient as the example and gives the apt line for Debian or Ubuntu:

```bash
sudo apt install python3-dev default-libmysqlclient-dev build-essential pkg-config
```

After configuring the DATABASES setting against two MySQL databases, migrations are run per service, including the separate student_module_history database:

```bash
./manage.py lms migrate
./manage.py lms migrate --database=student_module_history
./manage.py cms migrate
```

Static assets are built with npm run build, or build-dev for development. The README notes that pulling translations and collecting static files can be skipped for development sites. Then the two servers start, LMS on port 18000 and CMS on port 18010, and you should expect a mostly-headless platform until the MFEs are running.

## Where a bare-metal install goes wrong

The Studio SSO step is the clearest trap. Studio authenticates against the LMS through an OAuth application, and the README gives a development command that creates studio_worker and a client with a hardcoded client-id of studio-sso-key and client-secret of studio-sso-secret. Immediately above it, in capitals, the README warns not to do this in production because it will make your auth insecure.

The production variant is genuinely different, not just a flag change. You create the user and application without a secret, then log into Django admin at the oauth2_provider application page, open the application and copy its generated client secret. That secret goes into your private LMS_CFG yaml file or private Django settings module as SOCIAL_AUTH_EDX_OAUTH2_SECRET, with SOCIAL_AUTH_EDX_OAUTH2_KEY set to the client ID. Skip this and Studio appears to load while authoring fails.

Codejail is the second constraint. The README says the bare-metal setup requires configuring the system to work with codejail and links to the installation steps in the openedx/codejail repository. Codejail executes untrusted learner code in a sandbox. If you are not running courses that execute student code, you may not need it, but the README treats it as part of the bare-metal setup rather than an optional extra.

The third limitation is scope. This is the wrong tool if you want a single container that serves courses. It is also the wrong tool if you cannot run MySQL, Mongo and Memcached, or if you need the frontends from a different release than the monolith. Nothing in the README describes a supported mixed-version deployment.

## Open edX versus Moodle: monolith plus MFEs against a PHP application

Moodle is the obvious comparison for anyone choosing a self-hosted LMS, and the difference is structural rather than cosmetic. Moodle is a PHP application that ships its own interface; you install it, point a web server at it and you have a working site. Open edX splits the interface out. The README says most frontends have been migrated to micro-frontends that need to be installed and run separately, and names the Authoring MFE, Learner Home MFE and Learning MFE as the minimum for meaningful navigation.

That split buys independent frontend release cycles and lets a large deployment scale the LMS and CMS separately from the React apps. It costs you the single-artifact install. The monolith is also Python and Django, so the operational skill set is Python, Celery, MySQL, Mongo and Node rather than PHP and MySQL alone. The README's system list is the honest summary of that: Ubuntu 24.04, Python 3.12, Node from .nvmrc, MySQL 8.0, Mongo 7.x and Memcached.

If your team already runs Django services and Docker, the Open edX shape is familiar. If your team runs a LAMP stack and wants one directory to deploy, Moodle's model is closer to what you have.

## Licence, release cadence and upgrade cost

The repository is AGPL-3.0, stated in the README badge and in the LICENSE file at the top level. That is a copyleft licence with a network clause. If you modify the platform and let users interact with it over a network, the AGPL's obligations attach to the modified source. This is not legal advice, and the practical answer depends on how you deploy and what you change; but the licence is the first thing to put in front of whoever owns compliance at your organisation, before you plan customisations.

Upgrade cost is where the release list in the repository is less helpful than it looks. The recent releases shown are named-release/cypress.rc2 and cypress.rc1 from July 2015 and named-release/birch from March 2015. Those are old named releases, and the README points at Tutor and the Site Ops documentation rather than at this list for current deployment guidance. Treat the release list as historical, not as your upgrade path.

The maintenance signal is stronger: the repository is not archived, and the last push was on 2026-09-21, the day before this was written. There is also an experimental bare-metal workflow mentioned in the README, built on a development.py settings module that uses local.openedx.io domains, which the README says is not yet the recommended default. Anything built on that module should be expected to move.

## What to check before you commit a team to it

Work backwards from the frontends. Decide which MFEs you need, confirm their versions against the monolith release you intend to run, and only then plan the backend. The README lists a full set of MFEs expected to run by default, and a mismatch there produces a platform that starts cleanly and renders nothing useful.

Then confirm the three services and the sandbox on the actual host, not on a developer laptop. MySQL 8.0, Mongo 7.x and Memcached are hard requirements in the README's list, and codejail needs host-level configuration that a container image may not give you. If you cannot run codejail, decide now whether your courses execute learner code at all.

Finally, pick the deployment route deliberately. Tutor is the recommended production and development path and the community-supported one. Bare metal is explicitly the route for experienced administrators who accept limited support and take configuration into their own hands. Choosing bare metal for a small team is the decision that most often turns into an unmaintained fork.

## Conclusion

Adopt openedx-platform if you need an authoring environment and a delivery service you control, and you accept AGPL-3.0 plus a Tutor-based deployment. Do not adopt it if you want a single process you can pip install and run: the README says installing and running an Open edX instance is not simple and recommends a service provider first. Before committing, verify that the MFE versions you plan to run match your release, that the codejail sandbox is configured on the host, and that you can reproduce the studio-sso-key OAuth application setup in your own settings file.

## FAQ

### What is the Open edX Platform?

It is the repository that hosts the monolith at the centre of the Open edX platform, written in Python and JavaScript with heavy use of Django. It provides two services: CMS, which powers Open edX Studio for authoring content, and LMS, which delivers that content to learners.

### Is Open edX free?

The repository is licensed under AGPL-3.0, so the source is available under that licence. The README also notes that installing and running an instance is not simple and recommends a service provider with free trials as the easiest way to start.

### How do I install the Open edX Platform?

The README recommends Tutor, the community-supported Docker-based Open edX distribution, for production, and Tutor's development mode for developers. A bare-metal install on Ubuntu 24.04 with Python 3.12, MySQL 8.0, Mongo 7.x and Memcached is possible but documented as advanced and mostly undocumented.

### What is Open edX Studio?

Studio is the platform's learning content authoring environment, powered by the CMS service in this repository. It runs from the CMS process, which the README starts with ./manage.py cms runserver 18010.

### Does the Open edX Platform need micro-frontends to run?

The backend starts without them, but the README says that gives you a mostly-headless platform. To navigate the UI meaningfully you need at least the Authoring MFE, the Learner Home MFE and the Learning MFE running separately.

## Sources

- [License: AGPL-3.0](https://github.com/openedx/openedx-platform/blob/master/LICENSE)
- [openedx/openedx-platform on GitHub](https://github.com/openedx/openedx-platform)
- [Project website](https://openedx.org)
- [README](https://github.com/openedx/openedx-platform/blob/master/README.md)
- [Releases](https://github.com/openedx/openedx-platform/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/openedx-openedx-platform
