OEP-19: Developer Documentation#




Developer Documentation

Last Modified



Grant Goodman, Robert Raposa, Ned Batchelder, Nimisha Asthagiri


Cali Stenson




Best Practice



Review Period

2018-12-06 - 2019-01-11



Developers who work on the Open edX platform, both inside and outside of edX, need accurate and current documentation about platform architecture, APIs, and development best practices.

Developer documentation is defined as written specification, instructions, and resources for software developers who extend and contribute to the Open edX platform. It does not include documentation resources targeted for edX learners, educators, researchers, and Open edX operators. Those are out of scope of this OEP and maintained at docs.openedx.org.

Developer documentation is inconsistent and poorly maintained. Documents are also difficult to find. They exist in multiple locations, including Read the Docs, GitHub repositories, Confluence wiki, and Google Docs.

Development team notes used for project management, brainstorming, meeting notes, etc. as well as code comments that a developer may add to clarify or rationalize a code segment are out of scope of this OEP.


The best practices and guidelines captured in this OEP are intended to be followed (for example, co-locating docs in GitHub, classifying different doc types, consolidating on formats). We have omitted considerations that we intend to experiment upon and capture in future edits of this OEP or other OEPs (for example, ownership responsibilities, API documentation details, choosing between writing ADRs versus OEPs, etc).


  • We will use reStructuredText (rST) as our default documentation format for all developer documentation except for the exceptions outlined here. See the Format Rationale section below for more info on why RST.

    • Python docstrings that are going to be rendered in an Open API context should be formatted in Markdown.

    • When we need to embed active react components in the documentation to document frontend capabilities, MDX should be used.

  • The developer section of docs.openedx.org will contain the main index for all repo specific and system wide developer docs.

  • System wide decisions, best practices and processes will live in the open-edx-proposals repository.

  • ADRs, How Tos and other single repo impacting docs will live in a /docs folder in the impacted repo.

  • edX Inc. specific documentation such as notes, agile meeting artifacts, and documentation of edX specific process and decisions will live in Confluence.

A diagram that shows the different types of documentation and their relationships. This is further described below.

Agile Documentation Types#

With Agile development and Clean Code, we can minimize documentation (and its maintenance) since code should be readable and self-documenting. However, for long-term maintenance of a platform, the following types of developer documentation are still needed:



Open edX Proposals (OEPs) are a collection of system-wide technology decisions made by the Open edX community, in the form of best practices, architecture designs, and processes.

Answers the questions

  • What are the best practices and processes for developing on the Open edX platform?

  • How does system-wide framework X work on the Open edX platform? (e.g., Analytics, Authorization, etc).

  • Why was system-wide technology X or design Y chosen for the Open edX platform?


OEP Templates provides details for what constitutes a valid OEP format.


To establish software development coherency and efficiency with minimal centralized governance across a long-term maintained platform.

Location in GitHub

Stored and reviewed in the open-edx-proposals GitHub repo; published to Open edX Proposals Read The Docs.


OEP-1 describes the OEP review process. They will be maintained by the edX Architecture team.



Inspired by Nygard’s post, Architecture Decision Records (ADRs) are local lightweight documents of technical decisions co-located with their corresponding code. They provide rationale behind the code and the archeological path to their current state. The status of an ADR can be:

  • draft if the decision is newly proposed and in active discussion

  • provisional if the decision is still preliminary and in experimental phase

  • accepted once it is agreed upon

  • superseded with a reference to its replacement if a later ADR changes or reverses the decision

Note: Unlike code comments that focus on immediately surrounding code, ADRs provide the big picture context.

Answers the questions

  • What technical decisions were made for the component/feature in this repo/app/folder?

  • Why does this component/feature do X?


A sample template is provided below.


These records prove to be an invaluable technique for engineering teams to onboard new members, to understand discovered historical traces, to refer back to past decisions, and to support external oversight.

Location in GitHub

A local folder named decisions will be created within a docs folder in the repo/app/folder (for example, the edx/credentials/docs/decisions folder). The goal is to keep the decisions in as close proximity to the code as possible for their discovery and usage.


Since ADRs are inherently a historical trail of technical decisions, by design, they do not need ongoing maintenance.

A suggested ADR template:

0. Title For ADR
.. The title should be a short noun phrase. For example, "1. Django IDA" or "9. LDAP for Multitenant Integration"; filename should be lowercase with punctuation removed and spaces replaced by dash


**Accepted** *2023-05-11*

.. Standard statuses
    - **Draft** if the decision is newly proposed and in active discussion
    - **Provisional** if the decision is still preliminary and in experimental phase
    - **Accepted** *(date)* once it is agreed upon
    - **Superseded** *(date)* with a reference to its replacement if a later ADR changes or reverses the decision

    If an ADR has Draft status and the PR is under review, you can either use the intended final status (e.g. Provisional, Accepted, etc.), or you can clarify both the current and intended status using something like the following: "Draft (=> Provisional)". Either of these options is especially useful if the merged status is not intended to be Accepted.


.. This section describes the forces at play, including technological, political, social, and project local. These forces are probably in tension, and should be called out as such. The language in this section is value-neutral. It is simply describing facts.


.. This section describes our response to these forces. It is stated in full sentences, with active voice. "We will …"


.. This section describes the resulting context, after applying the decision. All consequences should be listed here, not just the "positive" ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and project in the future.

Rejected Alternatives

.. This section lists alternate options considered, described briefly, with pros and cons.


.. (Optional) List any additional references here that would be useful to the future reader. See `Documenting Architecture Decisions`_ for further input.

.. _Documenting Architecture Decisions: https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions

The author is encouraged to add other sections as appropriate, such as “Author Concerns”, “Related Decisions”, etc.



READMEs provide a top-level summary and intentional purpose of the repo/app/folder.

Answers the questions

  • What is the responsibility and purpose of this component?

  • What are the terms and definitions of this component’s ubiquitous language?

  • How can I navigate the documentation within and related to this component?


The details of what should be in a readme were codified in OEP-55 and can be found in the related README ADR


The future evolution and development of a component remains within the intended boundaries of the component’s responsibility. Otherwise, it invites unintended complexity and incongruity.

Location in GitHub

Since GitHub automatically renders the contents of the repo’s top-level README.rst file on the repo’s home page, README files will be located at the top-level of their corresponding repo/app/folder.


The development team that owns the component should keep its README updated.



How-To documents provide relatively long-term step-by-step instructions in using a feature/component/etc. For instructions that are expected to be ephemeral and short-lived, other alternatives such as Etsy’s FYIs can be explored.

Answers the questions

  • How do I install/enable/use/test/etc this component?


To provide concise recipe-style instructions to users of the component so they can get started quickly without needing to understand the technical nuances and code of the component.

Location in GitHub

A how_tos folder will be created within a docs folder in the repo/app/folder. The goal is to keep the How-Tos in synch with the code so that (1) developers running older versions of the code have the appropriately versioned information and (2) developers updating the component have easy access to update the corresponding How-Tos.


The developer and code reviewer that updates the component will be responsible for updating the relevant How-Tos in that repo (preferably in the same PR as the code changes).



API documentation provide information on interfaces for integrating with or enhancing the platform.

Answers the questions

  • What are the public and supported APIs for this component?

  • What are the request/response/authentication/etc protocol for this component?


Developers that use and integrate with the component have a clearly defined and consistently documented interface.

Location and tools

The documentation of APIs should be automatically generated and extracted from the code and its annotations. For example:

  • REST API interfaces should be automatically generated using Swagger.

  • The Open edX Learning Exchange (OLX) format should be automatically generated.

  • Plugin interfaces (e.g., Proctoring integration) should be automatically generated using Sphinx.

  • Public APIs (e.g., supported Javascript libraries, supported Python APIs) should be automatically generated using Sphinx.


Since they are automatically generated, API documentation do not need additional maintenance and will be in synch with their corresponding code.


This section summarizes the requirements for long-term developer documentation.

  • Discoverable. Users must be able to find the documentation that is relevant to their needs. This calls for a high-level index and search mechanism for finding content.

    • Search. For the time-being, we will make use of Google and GitHub’s search functionality for finding content since all developer documentation will be in GitHub. Certain IDEs may also have tools for searching.

    • Index. In the future, we will invest time in a better automated indexing tool to aggregate and structure the documentation. For the time being, we will manually create and maintain documentation indices at:

      • The developer section will include the landing page for developer documentation and be a container of orphaned and cross-repo developer documentation.

      • docs.openedx.org will be the main landing page for all Open edX documentation, including a link to the developer documentation index listed above.

  • Maintainable. Writers, editors, and reviewers must be able to create and modify documentation without too much effort.

    • Co-located. The closer the documentation lives with its corresponding code, the more likely it will be kept up-to-date.

      • For repo-specific documentation:

        • ADRs and How-Tos will live within docs folder(s) within the repo.

        • READMEs will be located as top-level documents in the repo/folder/app.

        • Documentation should not live within the code itself (e.g., in __init__.py modules).

      • For system-wide documentation:

        • OEPs will live within the open-edx-proposals repo.

        • If other system-wide documentation is needed, they will live within the developer section of the docs.openedx.org repo.

    • Exported Diagrams. In order to keep diagrams updated across time, they will need to be exported from whichever tool they were created in, with the exported version maintained in GitHub.

      • draw.io diagrams will be exported and imported as XML files.

      • Lucidchart diagrams will be exported and imported as Visio (VDX) files.

  • Version Controlled. Documentation must be maintained under version control in GitHub, for the following reasons:

    • Reviewed. They will be properly reviewed as defined by that repo’s process. Anyone in the Open edX community with access to the repo will have the ability to add, update, fix, and contribute to documentation by following the repo’s review and maintenance process.

    • Tagged. They will be appropriately in-synch with their corresponding code. For example, when an open edX instance runs an older named release, the operator can refer to the matching documentation for that version of the codebase.

    • Source Controlled. They will have the advantages of having source-control backed files, including sharing across multiple developers and robust storage.

Format Rationale#

We will use reStructuredText (rST) for all developer documentation.

  • rST scales up: it can be used for anything from docstrings to single-page documents to books to multi-volume book sets.

  • rST has a rich feature set, including inter-document links, table of contents, auto-collection of code documentation, list-formatted tables, semantic markup, and multiple output formats.

  • A single documentation format enables consistency. It also avoids conversion to rST when we require its additional features. Our experience has shown that these two benefits of standardization keep down the overall cost of documentation maintenance.

  • rST is the standard markup format for Python project documentation.

  • rST does not suffer from incompatible implementations, with different features supported differently by different renderers.

  • GitHub renders rST natively.

More details on these points are in Eric Holscher’s why rST over Markdown for documentation blog post.

Best practices#

  • We strongly recommend that rST documents auto-wrap rather than have fixed line lengths (of 120, for example), for the following reasons:

    • Both GitHub and popular IDEs support rendering of auto-wrapped files.

    • Auto-wrapping allows renderers to be responsive, automatically format according to the reader’s view width, and better supports split-window mode of development.

    • Developers don’t need to spend time continually reformatting lines whenever they edit their documents in order to remain within fixed line length limits.

    • Although GitHub’s diff-ing capabilities are currently better when line breaks exist, this seeming advantage actually disappears when developers reformat lines in a paragraph to adjust to line length limits.

  • Consistency across rST documents is not a requirement. However, you can use the raw version of this OEP as a reference example.

Learning rST#

Rejected alternatives#

Markdown Format#

We are choosing to not use Markdown (MD) for documentation. A single format enables consistency, and avoids conversions to rST when requiring additional features. See the Format Rationale section for more details. The Learning rST section has resources comparing Markdown and rST.


Currently edX uses Confluence for storing both long-term and short-term developer documentation. Confluence does provide a WYSIWYG editor, which makes its relatively easy to create and edit documents. Its transitory nature also provides an impetus to rapidly writing down notes and thoughts. Given this, we do expect some hesitancy with transitioning to writing rST files in GitHub. However, as described in this OEP, GitHub provides the benefits of versioning, reviewing, release-tagging, and co-locating, which we expect will result in better quality and maintenance of our developer documentation.

Confluence Usage and Migration#

We will continue to use Confluence for transitory and “edX private” documentation needs since it is already a hub of communication for both edX employees and the Open edX community. However, the long-term types of developer documentation listed in Agile Documentation Types will need to migrate to their new locations.


When migrating content from Confluence to GitHub, we will:

  1. Reformat it to rST and store it in the appropriate location in GitHub.

  2. Delete the content from the old page, with a forwarding link to the new Read The Docs location.

  3. Archive the old page, as explained below.


For sustainable maintenance of Confluence documents, ongoing cleanup will be implemented using Confluence’s useful Space Archive feature. All engineering related documents will be archived to the private Archive: Engineering space.

When a page is archived:

  • The page and its contents are no longer included in normal searches, thus keeping our search results de-cluttered.

  • The page no longer appears in Google searches.

  • Links to the old page are automatically forwarded to its new location in the Archived space (unless the old page’s containing space is entirely deleted).

You can search for archived pages using Confluence’s advanced search. From the Confluence search panel, select Advanced Search, then select Search archived spaces.



Since we will continue to use Confluence for certain types of documents, we will maintain the following two top-level indices for engineering related documents:

Next Steps#

  • Publishing: The intention is to have all rST documents published to Read the Docs.

  • Validation: The intention is to have all rST document changes in all repositories automatically validated as part of the Continuous Integration quality tests for any PR. See the edx-cookiecutters repo for examples.


Change History#


  • Minor update to the ADR template in OEP-19, providing a specific example for status. The new example provides a date format, and also removes the bullet that may be used if copying from the list of examples of status.


  • Remove references to the deprecated edx-developer docs.

  • Also update references to docs.edx.org to docs.openedx.org.

  • Pull request #411



  • Clarify how to provide a Draft status when the ADR PR is planned to be merged with a status other than Accepted, like Provisional.