MFE Rewrite — what's left to do
This issue tracks the remaining work to finish migrating Open edX off server-rendered
legacy pages and onto MFEs. It is organized by what needs to happen next, not by page
area, so the open work is scannable. Completed work is collapsed at the bottom.
Detailed history and per-row notes live on the (now unmaintained) Confluence page —
MFE Rewrite Tracker.
That page is being archived and banner-linked here for reference; this issue is the live home.
Goal: no default legacy pages by release "X"
How to read the tables
Each row shows what a user is actually served today, split into two columns because
vanilla Open edX and Tutor defaults diverge — and vanilla is the column that matters for
planning (anything that's MFE only because Tutor turns it on still needs to be made default-on
in the platform, and ideally the legacy view dropped). Next action is the concrete next step;
Notes holds the supporting context/caveats.
| Value |
Meaning |
MFE |
MFE served by default |
LEGACY |
Legacy view served by default |
REMOVED |
Legacy gone; MFE is the only option, no toggle |
REDIRECT |
Legacy URL survives only as a redirect |
N/A |
The MFE-vs-legacy split doesn't apply |
UNKNOWN |
Not established |
Bold (**LEGACY**) = verified against a merged PR or checked live in the 2026-07-29 review.
Trailing ? (MFE?) = inherited from the old doc's "default in Open edX" tag and not
verified — every MFE? is itself a work item (the default-sweep, task A2). Do not cite one
as fact.
DEPR context: umbrella #36108
("Various legacy Studio pages") is Closed with 52 tasks — strong signal most Studio rows
below are already done and just need confirming. The old doc is known to lag the code, so
where this issue and the Confluence page disagree, this issue is the more current.
🔴 Remove legacy — decided; MFE is the valid version (or the feature is dead)
No parity work or discovery needed — the legacy pages just need deleting.
| Page |
Vanilla |
Tutor |
Next action |
Notes |
Ref |
| Courseware: Search |
UNKNOWN |
UNKNOWN |
Remove the legacy in-course search Backbone UI. Not blocked (dead code); but full teardown of the shared openedx/features/course_search/ bundle is blocked by the cross-course search removal (#38941). |
Nothing loads the in-course UI; the learning MFE is the confirmed replacement. |
courseware.mfe_courseware_search |
| Discover New Courses |
MFE? |
MFE? |
Confirm the legacy code can be deleted, then remove it (DEPR #36785). |
Legacy page still exists; MFE is frontend-app-catalog. Covered by the Home/Catalog/Course About DEPR; handled together with Course About. |
#36785 |
| Course About |
MFE? |
MFE? |
Confirm the legacy code can be deleted, then remove it (DEPR #36785). |
Legacy page still exists; MFE is frontend-app-catalog. Covered by the Home/Catalog/Course About DEPR; handled together with Discover New Courses. |
#36785 |
| Discussions (legacy forum tab) |
LEGACY |
MFE |
Ready to remove; scope is in the DEPR (#38940). Blocked by: its Earliest Breaking Changes Unblocked date (2026-08-14) — proceed once it clears. |
Verified 2026-07-31: legacy is the vanilla default; Tutor forces the MFE on. Divided/cohorted-discussions config is separate → #38945. |
#38940 (fast-track DEPR) |
🟠 Flip the vanilla default, then remove — MFE exists but is off by default in vanilla
⭐ Confirmed divergences. Both toggles default False in edx-platform; they're MFE only
because Tutor turns them on. Short-term: make them default-on in the platform. Ideal: drop the
legacy view.
| Page |
Vanilla |
Tutor |
Next action |
Notes |
Ref |
| Course Dashboard (Learner Home) |
LEGACY |
MFE |
Default learner_home_mfe.enabled on in the platform, then drop the old dashboard. Blocked by: the cross-course search decision (#38941) before the dashboard can be dropped. |
Open discovery: does the programs dashboard depend on the old learner dashboard view? |
#35326 |
| Login / Registration |
LEGACY |
MFE |
Default FEATURES['ENABLE_AUTHN_MICROFRONTEND'] on, then start removing the legacy views. |
DEPR is now unblocked (custom registration fields landed in the MFE). Follow up with eduNEXT on the registration-extensions migration (Feanil). |
public-engineering#81 |
🟡 Build a replacement — legacy page with no MFE yet
These cannot just be removed; they need a replacement view built first.
| Page |
Vanilla |
Tutor |
Next action |
Notes |
Ref |
| Course Home: Custom Pages |
LEGACY |
LEGACY |
Build an MFE course-home tab that iframes CustomTabBlock. |
Scoped ~2h with two people; help wanted. Not the same as the (removed) Studio custom-pages UI. |
— |
| Course Bookmarks |
LEGACY |
LEGACY |
Build the MFE view for showing bookmarks. |
Bookmarks are created in the MFE, but "show my bookmarks" links to the legacy page (/courses/{id}/bookmarks/). |
— |
| Course Teams |
LEGACY |
LEGACY |
Build a replacement, likely a courseware tab in frontend-app-learning. |
Same pattern as the instructor dashboard tab. Cannot be ripped out. |
— |
| Courseware: Legacy Sequence View / LTI |
LEGACY |
LEGACY |
Dig into the replacement shape for the LTI provider case. |
Learning MFE covers ordinary learners; the LTI provider view is the gap (people LTI whole sequences into other LMSs). Effectively untested. |
#35803 |
| Instructor Dashboard (all pages) |
LEGACY |
LEGACY |
Continue building frontend-app-instructor-dashboard. Removing the legacy divided-discussions section + its course_discussions_settings_handler / discussion_topics endpoints is blocked by the DEPR RFC (#38945). |
Feature gap resolved 2026-07-31: cohort management is migrated (MFE uses /api/cohorts/v1|v2/), but divided/cohorted-discussions management is absent from the redesign. Discovery frontend-app-instructor-dashboard#225 decided to DEPR the legacy feature (assume it can go, let operators object) → DEPR #38945; those endpoints and their dashboard section stay until the RFC clears. |
#38945 |
🔵 Needs discovery — open questions (A5)
Not enough is known to act. This table is the tracker — open a sub-issue for a row only when
work on it actually begins; we are not pre-creating them.
| Page |
Vanilla |
Tutor |
Next action |
Notes |
Ref |
| ID Verification |
UNKNOWN |
UNKNOWN |
Discovery: which legacy IDV pages still exist, and can they be cleaned up? |
MFE lives in frontend-app-account. |
— |
| Course Home: Progress |
LEGACY |
MFE? |
Follow up with MIT (Peter); then reopen the DEPR. |
Legacy is still default in vanilla (Kyle). MIT keeps specific courses on legacy via a per-course flag because the MFE shows grades where the old page didn't. |
course_home_mfe.course_home_mfe_progress_tab |
| Courseware: Proctored Exam |
UNKNOWN |
UNKNOWN |
Outline the feature set on both sides, decide what to keep, involve product. |
Nobody could define parity. Contact Michael Roylance/Wrightman. |
edx-proctoring#1226 |
| Program Dashboard |
LEGACY |
LEGACY |
Research whether to convert it at all, given the sequences/pathways work. |
Row is internally inconsistent (in-development + "needs DEPR"). How does it relate to the learner dashboard (shared with the Course Dashboard discovery)? |
— |
| Course Certificates |
LEGACY |
LEGACY |
Research the current state; consider extracting as a plugin. |
Should've moved to Credentials years ago, never did, still used. ⚠️ Old URLs must keep working. |
— |
| Program Certificates |
LEGACY |
LEGACY |
Research the current state (together with Course Certificates). |
Credentials /credentials/{cert_id}. ⚠️ Old URLs must keep working. |
— |
| Track Selection |
LEGACY |
LEGACY |
Decide keep-and-rewrite vs DEPR. |
No MFE today; if kept it needs a rewrite, likely a small component in the new frontend site. |
course_modes.use_new_track_selection (?) |
| Course Messaging |
UNKNOWN |
UNKNOWN |
Establish what this page even is. |
Zero information about this row. |
— |
| Preview Language / dark_lang (LMS) |
LEGACY |
LEGACY |
Verify which pages the cookie affects; leaning toward removing the feature. |
MFEs ignore it (they follow the browser). CMS twin already redirected. |
#36271 |
| Basket / Payment |
N/A |
N/A |
Discovery: sort what stays as a checkout seam vs. what's dead. |
Not a simple removal. The purchase/upgrade integration (EcommerceService + ~11 upsell call-sites) is inert by default but exposes pluggable checkout hooks external tools may use. |
#38942 |
| Order History |
N/A |
N/A |
Confirm removability in the discovery. |
Ecommerce order history: an external MFE link (ORDER_HISTORY_MICROFRONTEND_URL) + the OrderView endpoint. Likely removable. |
#38942 |
| Studio: Pages & Resources |
LEGACY |
MFE? |
Discovery: establish what "off" serves and whether a legacy page exists at all. |
discussions.pages_and_resources_mfe defaults False in vanilla, so the MFE is off by default; Tutor likely on. (A4 finding.) |
discussions.pages_and_resources_mfe |
⚙️ In active development — MFE being built; not yet at the removal question
| Page |
Vanilla |
Tutor |
Next action |
Notes |
Ref |
| Studio: Unit Editor |
UNKNOWN |
UNKNOWN |
Land the last blocker, then remove the legacy unit editor. Blocked by: frontend-app-authoring#2620. |
The MFE unit editor is otherwise ready. |
#35261 |
| Studio: Text (HTML) Editor |
MFE? |
MFE? |
Finish the new editor, then remove the legacy one. Legacy removal blocked by the new editor still being in development. |
Flag new_core_editors.use_new_text_editor. |
#34692 |
| Studio: Problem (CAPA) Editor |
MFE? |
MFE? |
Finish the new editor, then remove the legacy one. Legacy removal blocked by the new editor still being in development. |
Flag new_core_editors.use_new_problem_editor. |
#35256 |
| Studio: Video Editor |
MFE? |
MFE? |
Finish the new editor, then remove the legacy one. Legacy removal blocked by the new editor still being in development. |
Flag new_core_editors.use_new_video_editor. |
#35257 |
| Studio: Library Authoring (all pages) |
UNKNOWN |
UNKNOWN |
Continue the relaunch, then resolve the dual-mode. Legacy removal blocked by the relaunch still being in progress. |
LIBRARY_MODE = 'mixed' means both are reachable at once — may need a third state. In development by Schema/OpenCraft/Axim. |
#32457 |
🏗️ Cross-cutting infrastructure — not pages, but blocks "headless"
Target end state: remove the JavaScript/SASS build chain from edx-platform entirely
(still run collectstatic, still serve some assets from Django views); XBlocks own their own JS
build. "We are nearly there."
| Item |
Next action |
Notes |
Ref |
Courseware: render_xblock |
Reduce to a thin wrapper over built-in views (keep the endpoint). |
Chromeless XBlock render endpoint iframed into learning/authoring; never fully removed. |
— |
| Courseware: Built-in XBlock Views |
Extract problem block + one other out of the platform build into xblocks-core. |
From xblocks-contrib; per-block flag xmodule.use_extracted_block.{tag}. |
#34827 · xblocks-core |
XBlock JS window globals |
Define an explicit interface + shim, then prune over time. |
Legacy XBlocks expect platform-provided objects on window (declare-your-deps → get only those; declare nothing → get everything). Brian + Kyle to discuss. |
— |
✅ Completed
Removed, migrated, or resolved — kept for reference
| Page |
Removed / migrated by |
| Studio: Logged-out Landing ("Howitworks") |
#36269 — removed, no replacement |
| Studio: Preview |
#36460 — legacy preview removed; native in learning MFE (merged 2025-05-14) |
| Studio: Course Custom Pages (legacy Tabs UI) |
#37557 — legacy Tabs UI dropped (merged 2025-11-20) |
| Studio: Maintenance (dashboard) |
#37432 — whole Maintenance dashboard removed (merged 2025-10-10); DEPR #36263 closed |
| Studio: Maintenance → Announcements |
#37432 — Announcements tool removed with the dashboard; DEPR #36263 closed |
| Studio: Maintenance → Force Publish Course |
Removed — "broken since it was first introduced" |
| Studio: Preview Language (dark_lang) — CMS |
#36271 — CMS page → redirect to LMS |
| Profile |
public-engineering#71 — frontend-app-profile |
| Account Settings |
public-engineering#71 — frontend-app-account |
| Course Home: Dates |
public-engineering#50 — frontend-app-learning |
| Course Home: Outline |
public-engineering#50 — frontend-app-learning |
| Courseware: Sequence (index) |
#35803 — courseware index + machinery removed (surviving sequence view tracked in 🟡) |
Studio pages — A4, verified 2026-07-30 against openedx-platform master 1746666137. Legacy
Django handler now redirects to the authoring MFE; the use_new_* flags are deleted and the API
serializer hardcodes them true as a compat shim under
#37497. Old URLs persist only as a
redirect + JSON data API (full removal tracked by #37497).
| Page |
Removed / migrated by |
| Studio: Logged-in Home |
A4 — course_listing redirects to MFE (views/course.py:707) |
| Studio: Advanced Settings |
A4 — redirect to MFE (views/course.py:1607) |
| Studio: Schedule & Details |
A4 — redirect to MFE (views/course.py:1473) |
| Studio: Grading |
A4 — redirect to MFE (views/course.py:1513) |
| Studio: Updates |
A4 — redirect to MFE (views/course.py:1392) |
| Studio: Import |
A4 — redirect to MFE (import_export.py:96) |
| Studio: Export |
A4 — redirect to MFE (import_export.py:343) |
| Studio: Files & Uploads |
A4 — redirect to MFE (asset_storage_handlers.py:226) |
| Studio: Content Outline Editor |
A4 — redirect to MFE (views/course.py:802); vestigial legacy_studio.course_outline flag safe to delete |
| Studio: Course Team |
A4 — redirect to MFE (views/user.py:59) |
| Studio: Textbooks |
A4 — redirect to MFE (views/course.py:1752) |
| Studio: Group Configurations |
A4 — redirect to MFE (views/course.py:1941) |
| Studio: Certificates |
A4 — redirect to MFE (certificates.py:144) |
| Studio: Checklists |
A4 — redirect to MFE (views/checklists.py:26) |
| Studio: Video Uploads |
A4 — legacy page redirect-only (video_storage_handlers.py:770); use_new_video_uploads_page default False now gates the MFE feature (edX video pipeline), not legacy code |
| Learner Record |
Resolved 2026-07-31 — no legacy learner-record page in edx-platform (no route/template); program records are served by the Credentials service + frontend-app-learner-record. Platform holds only the MFE registration, ENABLE_LEARNER_RECORDS (default True), and a link to Credentials public_records_url. |
Meta / cross-cutting tasks
- A1 — Inventory audit (Feanil + Brian, sub-issue already open): audit the HTML templates
still living in edx-platform, which URLs render them, and whether they have replacements —
anything with no row here gets added. This is the inverted audit direction the team agreed on.
- A2 — Default sweep (Brian): resolve every
MFE? above to MFE / LEGACY / REMOVED in
each column independently. Every MFE? in this issue is one item on that list.
- A4 — Studio confirmation ✅ done 2026-07-30: 14 Studio pages + Video Uploads verified
REMOVED (redirect-to-MFE, use_new_* flags deleted under #37497)
and moved to Completed; Pages & Resources reclassified to 🔵 discovery. See the A4 comment.
- A5 — Needs-discovery section is the tracker; open a per-row sub-issue only when work on that row begins (we are not pre-creating them).
For contributors
- Paste research/verification output as issue comments (there's a template in the comments)
so it can be folded back into these tables. Keep the tables terse; put evidence in comments.
help wanted is a good fit for Course Home: Custom Pages — small and well-scoped (~2h).
MFE Rewrite — what's left to do
This issue tracks the remaining work to finish migrating Open edX off server-rendered
legacy pages and onto MFEs. It is organized by what needs to happen next, not by page
area, so the open work is scannable. Completed work is collapsed at the bottom.
Detailed history and per-row notes live on the (now unmaintained) Confluence page —
MFE Rewrite Tracker.
That page is being archived and banner-linked here for reference; this issue is the live home.
Goal: no default legacy pages by release "X"
How to read the tables
Each row shows what a user is actually served today, split into two columns because
vanilla Open edX and Tutor defaults diverge — and vanilla is the column that matters for
planning (anything that's MFE only because Tutor turns it on still needs to be made default-on
in the platform, and ideally the legacy view dropped). Next action is the concrete next step;
Notes holds the supporting context/caveats.
MFELEGACYREMOVEDREDIRECTN/AUNKNOWNBold (
**LEGACY**) = verified against a merged PR or checked live in the 2026-07-29 review.Trailing
?(MFE?) = inherited from the old doc's "default in Open edX" tag and notverified — every
MFE?is itself a work item (the default-sweep, task A2). Do not cite oneas fact.
DEPR context: umbrella #36108
("Various legacy Studio pages") is Closed with 52 tasks — strong signal most Studio rows
below are already done and just need confirming. The old doc is known to lag the code, so
where this issue and the Confluence page disagree, this issue is the more current.
🔴 Remove legacy — decided; MFE is the valid version (or the feature is dead)
No parity work or discovery needed — the legacy pages just need deleting.
UNKNOWNUNKNOWNopenedx/features/course_search/bundle is blocked by the cross-course search removal (#38941).courseware.mfe_courseware_searchMFE?MFE?frontend-app-catalog. Covered by the Home/Catalog/Course About DEPR; handled together with Course About.MFE?MFE?frontend-app-catalog. Covered by the Home/Catalog/Course About DEPR; handled together with Discover New Courses.🟠 Flip the vanilla default, then remove — MFE exists but is off by default in vanilla
⭐ Confirmed divergences. Both toggles default
Falseinedx-platform; they're MFE onlybecause Tutor turns them on. Short-term: make them default-on in the platform. Ideal: drop the
legacy view.
learner_home_mfe.enabledon in the platform, then drop the old dashboard. Blocked by: the cross-course search decision (#38941) before the dashboard can be dropped.FEATURES['ENABLE_AUTHN_MICROFRONTEND']on, then start removing the legacy views.🟡 Build a replacement — legacy page with no MFE yet
These cannot just be removed; they need a replacement view built first.
CustomTabBlock.help wanted. Not the same as the (removed) Studio custom-pages UI./courses/{id}/bookmarks/).frontend-app-learning.frontend-app-instructor-dashboard. Removing the legacy divided-discussions section + itscourse_discussions_settings_handler/discussion_topicsendpoints is blocked by the DEPR RFC (#38945)./api/cohorts/v1|v2/), but divided/cohorted-discussions management is absent from the redesign. Discovery frontend-app-instructor-dashboard#225 decided to DEPR the legacy feature (assume it can go, let operators object) → DEPR #38945; those endpoints and their dashboard section stay until the RFC clears.🔵 Needs discovery — open questions (A5)
Not enough is known to act. This table is the tracker — open a sub-issue for a row only when
work on it actually begins; we are not pre-creating them.
UNKNOWNUNKNOWNfrontend-app-account.MFE?course_home_mfe.course_home_mfe_progress_tabUNKNOWNUNKNOWN/credentials/{cert_id}.course_modes.use_new_track_selection(?)UNKNOWNUNKNOWNN/AN/AEcommerceService+ ~11 upsell call-sites) is inert by default but exposes pluggable checkout hooks external tools may use.N/AN/AORDER_HISTORY_MICROFRONTEND_URL) + theOrderViewendpoint. Likely removable.MFE?discussions.pages_and_resources_mfedefaultsFalsein vanilla, so the MFE is off by default; Tutor likely on. (A4 finding.)discussions.pages_and_resources_mfe⚙️ In active development — MFE being built; not yet at the removal question
UNKNOWNUNKNOWNMFE?MFE?new_core_editors.use_new_text_editor.MFE?MFE?new_core_editors.use_new_problem_editor.MFE?MFE?new_core_editors.use_new_video_editor.UNKNOWNUNKNOWNLIBRARY_MODE = 'mixed'means both are reachable at once — may need a third state. In development by Schema/OpenCraft/Axim.🏗️ Cross-cutting infrastructure — not pages, but blocks "headless"
Target end state: remove the JavaScript/SASS build chain from
edx-platformentirely(still run
collectstatic, still serve some assets from Django views); XBlocks own their own JSbuild. "We are nearly there."
render_xblockxblocks-core.xblocks-contrib; per-block flagxmodule.use_extracted_block.{tag}.windowglobalswindow(declare-your-deps → get only those; declare nothing → get everything). Brian + Kyle to discuss.✅ Completed
Removed, migrated, or resolved — kept for reference
frontend-app-profilefrontend-app-accountfrontend-app-learningfrontend-app-learningStudio pages — A4, verified 2026-07-30 against
openedx-platformmaster1746666137. LegacyDjango handler now redirects to the authoring MFE; the
use_new_*flags are deleted and the APIserializer hardcodes them
trueas a compat shim under#37497. Old URLs persist only as a
redirect + JSON data API (full removal tracked by #37497).
course_listingredirects to MFE (views/course.py:707)legacy_studio.course_outlineflag safe to deleteuse_new_video_uploads_pagedefaultFalsenow gates the MFE feature (edX video pipeline), not legacy codeedx-platform(no route/template); program records are served by the Credentials service +frontend-app-learner-record. Platform holds only the MFE registration,ENABLE_LEARNER_RECORDS(defaultTrue), and a link to Credentialspublic_records_url.Meta / cross-cutting tasks
still living in
edx-platform, which URLs render them, and whether they have replacements —anything with no row here gets added. This is the inverted audit direction the team agreed on.
MFE?above toMFE/LEGACY/REMOVEDineach column independently. Every
MFE?in this issue is one item on that list.REMOVED (redirect-to-MFE,
use_new_*flags deleted under #37497)and moved to Completed; Pages & Resources reclassified to 🔵 discovery. See the A4 comment.
For contributors
so it can be folded back into these tables. Keep the tables terse; put evidence in comments.
help wantedis a good fit for Course Home: Custom Pages — small and well-scoped (~2h).