2025-05-08 Frontend Working Group Meeting Notes: frontend-base and the future of MFEs

2025-05-08 Frontend Working Group Meeting Notes: frontend-base and the future of MFEs

 Date, time, location

 Discussion topic(s)

1. MFEs as buildless libraries on NPM

To allow MFEs to be npm-installed into a “project” (see the next topic), they will be modified to export a top-level component that can be subsequently imported into a so-called “shell”. This has a few inescapable consequences:

  • They will no longer import or declare Header or Footer components, as going forward these will be the rendered by the “shell” (provided by frontend-base)

  • In order to allow for build-time configuration, they will be published as source-only NPM packages

    • E.g., potentially no longer bundle/transpile via babel in libraries (e.g,, would publish TypeScript source files if the library has it).

  • Common dependencies such as React, Paragon, Redux, and frontend-base itself will be declared as peer dependencies that will have to be upgraded in step

    • Helps standardize on dependency versions across MFEs.

      • Example caveat: have to upgrade React across all MFEs in a project at once.

      • Some MFE architectures do support any framework (React, Vue, etc.), but we are intentionally opting for using the same version of React, etc.

2. Project repositories

Project repositories will allow operators to choose to either build MFEs as separate SPAs (as they are now), or to run a build process that includes them all into a single one, all while permitting them to commit local configuration independently.

  • Projects would define its own package.json and a site.config.js (equivalent to today’s env.config.js).

  • No need to checkout frontend-base and install MFEs into that checkout; instead, tutor-mfe creates a new directory for a project.

    • Open edX will show an example project, but projects are intended to be operator-specific.

  • Direct dependencies on frontend-base and MFEs (from published NPM versions).

  • The project itself is not intended to be published to NPM.

  • The built project (single npm i in the project) output would be deployed/served.

  • Projects = domain-driven design

    • E.g., should there be a learner-focused project (domain) vs. an authoring-focused project vs. an enterprise project, etc.?

    • [consideration] Docs and best practices around treating projects as “domains”.

3. Should we deprecate webpack? If so, for what?

While it’s not a given that we will be moving off of webpack for Ulmo, there are options. rsbuild is reported to be more compatible with webpack configuration (of which we have a lot) and to be faster than Vite, but Vite has apparently been around a little longer. Are there any reasons why one is clearly better than the other, for us?

  • Open question: is it possible / should we be bundler agnostic?

    • [Brian] Should pick one, but should be forward-looking and has standard features across bundlers.

    • [Regis] nothing magic/special about webpack, shouldn’t be too much of a concern.

  • Convention over config

    • Rely on standard, best practices in the broader JS ecosystem rather than defining our custom boilerplate.

    • Config is hard. Difficult to understand/parse base options vs. relying on defaults.

  • [inform] React Router 7’s framework mode (using SSR) relies on a Vite plugin under-the-hood; without Vite, React Router 7 would always need to run in library mode.

  • Prioritization concerns

    • Should we tackle this now vs. focus more on frontend-base?

    • Incremental: try to remove the custom boilerplate as much as possible while still staying on Webpack without doing a big bang cutover/change.

      • What’s fancy/cute vs. what’s not?

4. Server-side Rendering

It’s unlikely we’ll have time to do SSR for Ulmo, but given its performance advantages for learners and other end-users of the platform, it would be wise not to do anything to jeopardize the option to adopt it - or something like it - in the future. This is the primary reason we’re foregoing the implementation of module federation (though not the only one: see the following topic.)

  • Can it be up to the operator

5. Macro-frontends

There’s a much easier way to share code between MFEs than module federation: we can simply move all the code into a single, monolithic repository. The Authoring MFE already does this for Studio: why not do the same for the LMS? Reducing bundle size, increasing build speed, dependency standardization, deduplication, maintenance… All of this becomes considerably simpler.

6. Wishlist

Time permitting, we can discuss popular wishlist items such as the following (from @Braden MacDonald's latest one):

  • Better error handling

  • Typescript!

  • A separate, fully typed REST API client based on React Query hooks

  • Get rid of Redux to make it easier to reason about data and state

  • Simpler plugins

  • More slots

  • Simpler MFE configuration

🎥Recording

 Participants

Adam Stankiewicz, Adolfo Brandes, Brian Smith, Daniel Wong, Diana Villalvazo Salas, Jacobo Dominguez, Jesse Stewart-WGU, Max Frank, Ram Chandra, Regis Behmo, Sarina Canelake, tony busa

🤖 Summary

Here's an LLM-generated, human-reviewed summary of the meeting.


1. Review of Micro Frontends (MFEs): Pros & Cons

Pros:

  • Team Independence & Parallel Development: The original rationale from the edX era was to enable faster, independent development.

  • Rapid Deployment: Only parts of the frontend need to be deployed, reducing risk.

  • Modern Tech Stack: Use of React, TypeScript, and SPA architecture improves developer experience.

  • Operational Simplicity: Easy to deploy static assets, which works well with CDNs.

  • Separation of Concerns: Backend and frontend can evolve independently with domain-specific expertise.

Cons:

  • Maintenance Overhead: Upgrades (e.g., React, Node) require many PRs (e.g., 12+), adding cognitive and operational complexity.

  • Duplication & Inefficiency: Libraries like Paragon are bundled into each MFE, increasing bandwidth and load time.

  • Customization Pain: Difficult to achieve consistent theming or behavior across MFE boundaries.

  • Fragmentation: Inconsistent headers/footers, Redux usage, tech stacks.

  • Feature Gaps: Some features (e.g., comprehensive theming, global announcements) were lost in the transition from Django-rendered pages.

  • Configuration Complexity: MFE plugin setup and environment handling (e.g., BASE_URL) are inconsistent.

  • Poor Web Vitals: Users face long load times (e.g., LCP > 4s), particularly on low-bandwidth networks.


💡 Proposed Solutions

1. Frontend Base & Buildless NPM Packages

A new approach—Frontend Base—was proposed to streamline development and deployment:

  • MFEs become Buildless NPM Packages:

    • Published as unbundled TypeScript.

    • Only export core components (e.g., Profile page logic) without headers/footers.

  • Single Shell App:

    • Orchestrates routing and rendering.

    • Handles shared elements like headers/footers.

Benefits:

  • Cleaner separation of concerns.

  • Simplified updates and maintenance.

  • Easier customization using peer dependencies and centralized site config.

  • Supports Tutor and bare-metal deployments equally.

2. Project Repositories

  • A new structure will include a “project repository” per operator.

  • This will contain:

    • package.json for managing MFE dependencies.

    • Site-wide configuration (e.g., site-config.tsx replacing mconfig.jsx).

  • One single build, rather than building each MFE separately.

3. Webpack Deprecation

Debate on whether to:

  • Remove Webpack's complex configurations.

  • Migrate to newer, faster bundlers like RSBuild or Vite.

Consensus: prioritize reducing Webpack complexity now, migrate later.

4. Server-Side Rendering (SSR)

Explored SSR benefits:

  • Faster time-to-interactive, especially important in low-bandwidth regions.

  • Discussed leveraging React Router v7’s Framework Mode, which integrates tightly with React for SSR.

Agreed that SSR should remain optional and not block immediate progress.

5. Domain-Driven Consolidation

Long-term idea:

  • Group MFEs into macro frontends based on domain (e.g., learner, authoring).

  • Reduce repo sprawl and simplify maintenance.

  • Keep the door open for shared REST clients and standardized hooks (e.g., React Query).


📝 Notes on Communication

  • A wiki and Slack thread contain deeper background.

  • OEP-65 may be amended or replaced post-prototype.

  • Feedback welcomed via Slack or directly to Adolfo.

 Action items

  • @Adolfo Brandes will finalize a prototype for Frontend Base and convert one MFE (e.g., Learner Dashboard) to test.

  • @Brian Smith will look into Renovate configuration too see if there's a way to limit update PRs to dependencies that are explicitly defined in package.json - in other words, no PRs to update transitive dependencies in package-lock.json.

 Decisions

  1. We will move forward with the proposal for experimental release during Ulmo, in particular items 1. and 2. as outlined above, with the move to deprecate Webpack as a nice-to-have.