How Open edX theming works across the LMS and micro-frontends
Theming in Open edX is done in layers, and each layer has to be changed in its own way. A team that wants learners and course authors to see its own brand must plan for the legacy Django-rendered pages of the LMS and Studio, the React micro-frontends that now render many learner and author screens, and the surfaces outside both, such as system emails and course certificates. These pages look like one product, but they are assembled from parts that take changes differently. A change that works on a Django template may do nothing on an MFE page, and the reverse is also true. Plan the branding work as a list of layers, each with its own method, before anyone edits a file.
Branding is harder than it looks because the LMS and Studio, the micro-frontends, emails and certificates each accept changes through different mechanisms. Legacy pages are styled through the platform's theme and template layers, while MFEs are built and deployed as separate applications that expose frontend plugin slots for extension. Emails and certificates have their own templates and configuration. Confirm, for each surface, which mechanism applies in your target release. Check the Tutor documentation for the theme and build hooks your Tutor version supports, because the mechanics change between releases and should not be assumed from older guides.
Release choice is a constraint you cannot work around. Open edX states that the latest named release is the only supported release, and Verawood, published on 30 July 2026, is the current one. A brand package built against an older release will need rework when you move forward, and a theme that depends on internals of a release you have left behind will not receive support. Ask your implementation partner or internal team to name the release they are targeting and to show which theming surfaces they tested on it, including the frontend plugin slots that Verawood added.
Tutor is the official Docker-based distribution for production and local development, so it is the natural place to keep brand configuration, theme assets and plugins. The platform is licensed under the AGPL, which means brand work must stay outside the core edx-platform code. Keep logos, colors, templates and plugins in Tutor configuration, theme repositories and plugins, so that a platform upgrade replaces the core without erasing your work. Treat any direct edit to core code as a fork you will maintain indefinitely. Ask your legal team to confirm which AGPL obligations apply to your hosting and distribution model.
Before scoping, list every surface your learners and authors will see, and mark which mechanism changes each one. Check three things: the release you will run, whether each surface is served by the LMS, Studio or an MFE, and who owns the assets for logos, colors, email copy and certificate templates. Each unclear surface is a risk to plan for, because an unbranded page in a learner's path damages trust quickly. Use this inventory as the input to the detailed decisions that follow, and do not start asset production until every surface has an owner and a method.
Which parts of Open edX carry the brand
Open edX brand appears in several places that are built and owned differently, from server-rendered LMS and Studio templates to React micro-frontends and transactional email. Each surface needs a different kind of change, so the team should map them before choosing an approach, and confirm which extension points exist in the release it runs.
Legacy LMS and Studio templates
Many pages a learner or author sees are still rendered by Django templates in the legacy LMS and Studio. Branding these usually means template overrides and stylesheets delivered through a theme or a Tutor plugin, not edits to edx-platform itself. Platform engineers usually own this layer. Check which pages still render server-side in your release, because some views have moved to micro-frontends and will not respond to the same overrides.
Learner and instructor micro-frontends
The learner dashboard, course pages and the redesigned instructor dashboard are React micro-frontends that load separately from the core platform. Brand changes here rely on frontend build configuration, design tokens or frontend plugin slots, depending on what the release exposes. Frontend developers usually own this work. Confirm the build and deployment path for each micro-frontend you customize, since each one is rebuilt and released on its own.
Studio sidebar and authoring screens
Verawood introduced a new Studio sidebar, so authors now see brand elements in a different place than in earlier releases. Changes to this area should be planned against the sidebar's supported extension points rather than by editing its components directly. Course authoring leads should review the result, because the sidebar is where course teams spend most of their working time. Confirm which sidebar slots your release provides before scoping design work.
Frontend plugin slots in Verawood
Verawood added new frontend plugin slots, which let a team insert or replace UI elements without forking the micro-frontend source. These slots are the preferred route for branding that must survive upgrades. Plan to confirm the exact slot names, their location and their stability in the release you run, because slot availability differs between releases. Keep a record of each slot you use so the upgrade team can retest it.
Header, footer and site configuration
The header, footer and site-wide logos, colors and links are often controlled by configuration values rather than code. Changing these through the platform's configuration keeps the change visible and reversible, and it is usually the first step in any branding project. Site administrators and product owners typically own the copy and assets. Check that every configuration value is stored in version control with the rest of the deployment, so it survives a rebuild.
Emails and certificates
Enrollment, account and course emails, along with completion certificates, carry the brand outside the browser and are often overlooked until launch. Email templates and certificate templates are customized separately from web pages, and each has its own rendering and testing needs. Communications and learning operations teams usually own the wording, while engineers own the templates. Send test messages and generate sample certificates across the mail clients and formats your learners use.
Choosing the branding approach for each layer
This table compares five ways to brand an Open edX deployment, from site settings to forked platform code. Read each row for the layer it fits, the work it adds to every rebuild and the upgrade risk it carries into the next named release. The main takeaway: forking edx-platform or an MFE is the option most likely to block upgrades, while the other four keep custom work separate from platform code.
| Approach | When it fits | Operational cost |
|---|---|---|
| Configuration-only branding through site settings | Logo, site name and basic text where site configuration reaches. Confirm each setting for your release. | Lowest effort to change and rebuild. Little upgrade risk. Test scope is mostly the pages the settings touch. |
| Tutor theme packaged as a plugin | A consistent visual theme across the legacy LMS and Studio, built and deployed from one package. | Rebuild the Tutor image when the theme changes. Retest after Tutor upgrades. Your team owns the theme package. |
| Frontend plugin slots for MFE changes | Adding or replacing content in MFE areas the release exposes as slots. Confirm which slots your release provides. | Plugin code stays outside platform source. Retest each slot after an MFE upgrade and confirm slot behavior at each release. |
| Full custom MFE build | Branded flows that slots cannot reach, such as a new layout for a micro-frontend page. | A build and deploy pipeline for each custom app. Full regression scope on each release. Your team owns the code and its dependencies. |
| Fork of edx-platform or an MFE | Changes inside platform source where no plugin point exists. Consider only after the other options are ruled out. | Most likely to block upgrades. Every upstream merge may conflict with your changes. Your team owns the fork for as long as it runs. |
Building a brand package with Tutor, step by step
This sequence takes an Open edX brand from a list of branded surfaces to a tested Tutor build that covers the legacy LMS, Studio, the React micro-frontends, and the emails and certificates learners receive. Each step ends with a check you can run before moving on.
Inventory every branded surface and its owner
Before changing any file, list every place the brand appears: the learner dashboard, course pages, Studio, the instructor dashboard, login and registration, the header and footer, transactional emails, certificates, and any external pages linked from the site. Record which layer renders each surface, whether it is the legacy LMS templates, a React micro-frontend, or configuration, and name an owner for each item on the client side who will approve it. Done means you have a signed-off inventory that maps each surface to a layer and an approver, so no surface is discovered late in testing.
Set platform and site configuration for names, logos and colors
Start with the settings the platform already exposes for the site name, logos, favicon, colors and contact details, so the brand works before any custom templates are written. Confirm with the Tutor documentation for your version which configuration keys control these values and how they are applied to the LMS and Studio, since key names change between releases. Keep these values in your Tutor configuration rather than editing containers by hand. Done means the LMS and Studio show the correct name, logo and colors after a rebuild, with the values traceable to one configuration file.
Create the theme package in its own repository
Create a theme package in a dedicated repository, separate from the Tutor configuration and from any custom XBlock or plugin code. Place the SCSS overrides, template overrides and static assets there, and keep a short README that states which release the theme was built against and how to rebuild it. The repository should be reviewable by your design and engineering leads and tagged so each release of the brand can be reproduced. Done means a clean checkout builds the theme locally with the steps in the README and produces the same output twice.
Package the theme as a Tutor plugin and build images
Wrap the theme package in a Tutor plugin so the theme is installed into the images through Tutor's plugin mechanism instead of being copied into running containers. Enable the plugin in the Tutor configuration, then build the images and deploy them to a non-production environment. Check the Tutor documentation for your version for the current plugin layout and build commands, and confirm them there rather than relying on examples. Done means a freshly built image in a test environment serves the new theme on the LMS and Studio, and rebuilding from the same tag gives the same result.
Apply frontend plugin slot changes to the micro-frontends
Brand the React micro-frontends through their frontend plugin slots where the slots allow it, instead of forking the applications. Identify the slots that cover the header, footer and other surfaces in your inventory, check which slots your release provides, and write the slot configuration as a plugin. Then rebuild the affected micro-frontends and redeploy them through Tutor. Where a surface has no slot, record it as a gap that needs either an accepted workaround or a deliberate customization decision. Done means every micro-frontend surface on your inventory is either branded through a slot or listed as an open gap with an owner.
Review learner dashboard, course page and Studio
Run a visual pass on the surfaces most learners and authors see first: the learner dashboard, a course page with enrollment open, the courseware player, and Studio's course outline. Use a set of test accounts with different roles, check text, logos, colors, contrast and navigation at common desktop and mobile widths, and compare the results against the approved inventory. Log each defect with the surface, the layer and the step that owns the fix. Done means the checklist has no open items for these four surfaces, and the client approver has signed off on the screenshots.
Review emails and certificates before release
Review every transactional email the platform sends, such as enrollment, account and password messages, and the certificate templates that learners download or share. Confirm the sender name, footer, logo, legal text and links resolve to the correct sites, and render the emails in common mail clients as a separate check. Confirm the certificate template against the wording your organization must show, and have the approver check it on a test course. Done means every email and certificate on the inventory has been sent or rendered in a test environment and approved in writing before the brand is promoted to production.
What to customize without forking the platform
The key decision in Open edX branding is which changes go through extension points and which edit upstream code or markup. Changes that go through extension points survive upgrades far better than changes that edit files the platform generates. Brand assets, configuration values, and components inserted through documented hooks are the safer group. Template overrides, stylesheet rules that target generated class names, and copied micro-frontend source sit in the riskier group. Draw this line before design work starts, because it determines how much of the branding will need rework at each release.
Frontend plugin slots and Tutor plugins let a team insert or replace React components while keeping its code in a repository it controls. Open edX Verawood added new frontend plugin slots, so the first check is whether the components you need to change have a slot in the release you plan to run. Tutor's plugin and hooks system is licensed under Apache 2.0 and lets your plugin add configuration, patches and assets without modifying the upstream repositories. Confirm which Tutor version your plugins target and test them against it before committing to a design.
Template overrides and stylesheet changes are fragile across named releases because the markup beneath them changes. An override that matches a template or selector may keep working through one release, then fail quietly after the next, leaving a page that looks almost right. Copying micro-frontend source into a private fork is more durable on paper but creates a maintenance branch. That branch must be merged on every release, and the merge effort recurs for as long as the fork exists. Ask any partner to estimate both the merge work and the testing it requires, in writing, before you choose this route.
Keep a written register of every override, with its reason, the file or component it touches, the owner, and the Open edX release and Tutor version it was tested on. Review the register at each upgrade and mark which entries can move to a plugin slot or Tutor plugin. This list is the fastest way to estimate upgrade effort and to explain to auditors or executives why a given change exists. For the wider plugin, Django and XBlock work, see the Open edX customization and upgrades topics.
What drives Open edX theming effort and how to keep it down
This table lists the factors that move theming cost and duration, how each one changes the work, and how to keep it contained. Read each row as a question to put to your partner or internal team before agreeing scope. The main takeaway is that most effort comes from the number of surfaces and brands you change, so limiting overrides and sharing one brand package usually matters more than any single visual decision.
| Driver | Why it changes effort | How to keep it down |
|---|---|---|
| Number of branded surfaces | Each LMS page, Studio view, MFE page and header or footer adds design, build and test work across both the legacy LMS and React micro-frontends. | Agree a written list of surfaces in scope. Brand through shared variables and styles, and limit page-level overrides to the few screens that need them. |
| Number of sites or organizations | Each organization with its own brand needs its own assets, color rules, logos and review cycle, and multiplies verification effort. | Use one shared brand package with per-organization configuration values. Add a separate package only where legal or contractual identity requires it. |
| MFE components changed beyond configuration | Changing component code rather than configuration or frontend plugin slots creates work that must be re-checked on every upgrade to a new named release. | Ask for a list of every component touched. Prefer configuration and frontend plugin slots, and treat any change to core component code as a cost to justify. |
| Email and certificate templates | Transactional emails and certificates are separate templates with their own layouts, variables and rendering checks in each language and client. | Confirm which templates are in scope. Reuse the brand package for colors and logos, and restrict custom layout to the templates learners and employers actually see. |
| Accessibility review | Contrast, focus states, keyboard navigation and screen reader behavior must be checked for each new color, layout and component change. | Set a fixed accessibility checklist up front. Ask for the test method and which assistive technologies and browsers the quote covers. |
| Translations and locales | Brand text, navigation labels and templates must be translated and checked in each language, and right-to-left layouts need separate review. | Confirm the list of languages and which strings are in scope. Keep brand copy short and move it into translatable resources rather than hard-coding it. |
| Environments that must be rebuilt | Each environment, including development, staging and production, must be rebuilt and checked after theme or build changes, so every extra environment repeats the work. | Ask how many environments the quote covers and how many rebuilds are included. Automate builds through Tutor so each rebuild is repeatable. |
How branding differs by deployment model
On a single Tutor host, the LMS, Studio and supporting services run in one Docker-based installation. The brand package is applied through the Tutor configuration and built into the images on the same machine that serves learners, so there is one build and one place where static files are served. Styling stays consistent because every request reaches the same build, and the main risks are release timing and browser caching.
- Build and delivery: The brand is applied as part of the Tutor configuration and image build, then deployed with the same commands that update the platform.
- Asset serving: Static files are served by the host's web tier, so LMS pages and MFE bundles follow one path that you can check directly.
- Browser caching: Learners may keep older stylesheets after a release. Confirm how your Tutor version names and invalidates asset bundles.
- Shared cache: There is one application node, so the shared cache does not affect styling consistency, though the Django cache backend still matters for performance.
- Rebuild scope: Any brand change requires a rebuild and redeploy of the affected images, so schedule a maintenance window for it.
Confirm in the Tutor theming documentation for your version how assets are generated and where the LMS and MFE bundles are served before you set your release steps.
Behind a load balancer, several LMS and Studio nodes must render the same brand. Each node holds its own copy of the build unless you distribute it deliberately, and the load balancer spreads requests across all of them. A node that missed a build can serve old styling to some learners while others see the new theme, so consistency depends on how the build reaches every node and how the shared cache holds data that all nodes read.
- Shared cache: Multi-node deployments need a shared Django cache backend such as Redis or Memcached, so every node reads the same cached data.
- Single artifact: Build the brand once and deploy the same artifact to every node, then record its version so you can compare nodes.
- Asset origin: Serve static assets from one origin or a shared store so all nodes return the same file names and hashes.
- Rolling updates: After each node is updated, check the brand version on that node before it returns to the pool.
- Intermediate caches: Session stickiness, reverse proxies and any CDN can keep old CSS alive, so define a purge step for every brand release.
Confirm which component serves static assets in your load balancer design, and whether your MFE bundles come from the same origin as the LMS, before you agree on a rollout order.
With tutor k8s, the brand is still built into container images, but the cluster decides how many pods run and when they are replaced. A rolling update can leave some pods on the old brand and others on the new one for a period, and the shared cache must be reachable by every pod. Ingress, any CDN in front of it and the storage used for uploaded media all shape how assets are served and cached.
- Image versioning: Tag brand images per release so a rollback restores both the platform code and its styling together.
- Shared cache: Redis or Memcached must be reachable by all pods, and as a service you run, it needs sizing, monitoring and backups.
- Ingress caching: Set cache headers for each file type at the ingress or CDN layer, and confirm them with a request test after each release.
- Overlapping versions: Test the brand on both old and new pods during the rollout, because learners may hit either one.
- Media storage: Decide whether uploaded brand assets, such as logos, persist when pods are replaced, and where they live.
Confirm the asset path from ingress to pod with your platform team, and check the tutor k8s configuration documentation for the cluster version you plan to run.
In an air-gapped network, the brand package cannot fetch dependencies from public registries during the build or at runtime. Every build input, including fonts, images, theme dependencies and base container images, must come from an offline build process or an internal artifact registry. The asset path stays inside your network, so the team that owns the environment also owns every brand update and its transfer.
- Offline build: Build the brand on a connected build system or within an approved process, then move the signed artifacts across the boundary under your transfer policy.
- Internal registry: Mirror the container images and packages the brand needs into an internal artifact registry before go-live.
- External references: Remove external font, script and analytics references from the brand package, since they will fail or send data outside the network.
- Internal caching: Any CDN may be an internal reverse proxy, so confirm its configuration and cache rules within the network.
- Update cadence: Each brand change repeats the transfer and approval steps, so include them in your release calendar.
Confirm with your security team which transfer and approval steps apply, and test that every page and asset loads with external egress blocked.
Keeping brand changes from creating security gaps
Brand work looks cosmetic, but it changes HTML, scripts, images and configuration that run in every learner's browser and sometimes in the server's trust boundary. The cards below cover where that risk enters an Open edX theme and the control that keeps each entry point reviewed. Full hardening of the platform is covered in the security hardening topic.
Third-party scripts in headers and footers
Headers, footers and custom page templates in an Open edX theme can carry analytics tags, chat widgets or survey embeds added by marketing teams. Each script runs with the LMS origin's access to learner sessions, so an unreviewed tag is effectively code running in your platform. Require that every script source is listed in the theme repository, reviewed through code review, and checked against the content security policy that the deployment sends.
Content security policy review
A content security policy tells the browser which script, style, image and frame sources the LMS and MFEs may load. Brand changes often add a new external domain for a logo, font or embed, and that addition quietly widens what the page can load. Ask the team to review the policy each time a theme release adds an external origin, and confirm which policy directives your Tutor configuration actually sets.
Injected HTML in announcements
Site announcements, banners and HTML fields in the LMS and some MFE components accept markup entered through admin screens. Markup pasted from an external source can include scripts or hidden links that a learner's browser executes. Decide which roles may publish rich HTML, sanitize pasted content, and test a banner with a script payload in staging before it reaches production.
Uploaded logos, favicons and images
Logos, favicons and social preview images are uploaded files that the platform serves to every visitor. Restrict uploads to image types the platform expects, check file size and format, and serve them from the media storage path rather than from an arbitrary URL. Confirm that the upload path and the storage bucket permissions match your data classification, because public media storage is readable by anyone with the link.
Secrets kept out of the theme
Theme repositories are copied between teams, cloned onto laptops and sometimes shared with agencies, so they should never hold API keys, SMTP passwords or client secrets for SSO providers. Keep those values in Tutor configuration and the environment for your deployment, and scan theme repositories for credential patterns before merge. Confirm where each secret is stored and who can read it on the server.
Who can change branding in production
Site appearance settings, theme selection and announcement tools are reachable from staff accounts, and a single account with broad rights can change what every learner sees. Limit production brand changes to a named group, separate it from course authoring roles, and log each change with its author. Review these accounts on a schedule and remove access when a contractor's engagement ends.
How to verify the brand works and fails safely
Before a branded Open edX release reaches learners, the team should be able to show two things: the brand renders correctly on every page that matters, and the platform can return to the unbranded build without losing course data. Treat these as separate tests. The first is a visual and functional check. The second is a rollback rehearsal in staging that proves the fallback works before anyone needs it in production. Start with visual regression checks on the main learner, instructor and Studio pages. For the LMS, that means the course home, course outline, a unit with video and problem components, the learner dashboard, the account and profile pages, and the enrollment and checkout pages. For the instructor side, include the redesigned instructor dashboard in Verawood and the Studio sidebar, since both have their own styling. Capture baseline screenshots from the unbranded build, then compare them against the branded build in every browser and device class your organization officially supports. Confirm that list with your own support policy before writing the test matrix. Keep the baseline and the comparison outputs as release evidence.
Next, run accessibility checks on the components you changed, not on the whole platform. Focus on color contrast for text, links, buttons, focus indicators and error messages against each new palette. Then check keyboard navigation: tab order through the header, the MFE navigation menu, course outline and any modal dialogs, with visible focus at every stop. Brand changes often break focus outlines or hide skip links, so test those explicitly. Automated scanners catch some of this, but a person working only with the keyboard should walk each changed flow. Record which components you tested and which you did not. Independent accessibility testing can be scoped separately if your obligations require a third-party assessment, and DeployOpen can scope that work as its own engagement.
Check the outputs that sit outside the web application. Send test emails for enrollment, password reset, account activation and any custom notifications, and inspect the HTML and plain-text versions in several mail clients. Generate a sample certificate and confirm logo placement, signatory text and the verification link. Then force the error pages: a 404, a 500 response and a maintenance page, so you know the branded templates load and that the default pages still appear if a template is missing. Each of these depends on different template paths, so a theme that works in the LMS can still leave emails unbranded. Define what a failing build looks like before you test, so the team can recognize it quickly. The usual failures are a missing component (a header or footer that renders empty or raises an error in the console), a broken stylesheet (unstyled pages, overlapping layouts or fonts falling back to system defaults), and a blank MFE page (a micro-frontend that loads a blank screen because its brand package or a plugin slot did not resolve). Write these as pass or fail criteria in the test plan, with the page, the expected result and the owner who signs off.
The rollback test is the most important check in this section. In a staging environment built from the same Tutor configuration as production, deploy the branded theme, then switch the theme setting back to the default and redeploy the affected services. Confirm the LMS, Studio and MFEs all return to the unbranded appearance, and that course content, enrollments, grades, user accounts and certificates records are unchanged. Compare database record counts and a sample of course and learner records before and after the switch. Theming should change presentation only, so a rollback that touches data indicates a configuration problem you need to fix before launch. Document the exact commands, the people who run them and the time each step took in your environment. Finally, decide who can trigger a rollback in production and what they check afterward. Ask your implementation partner to confirm how brand packages and plugin slot configuration are versioned, and whether the unbranded build can be redeployed from the same image or configuration tag. Keep a rehearsed runbook with a go or no-go checkpoint, and test it again after each Open edX upgrade, because a release change can alter how themes and micro-frontend builds resolve.
Questions teams ask before branding Open edX
Can our team brand Open edX ourselves without an outside partner?
Yes, if your team has frontend and Django skills and time to maintain the changes. Open edX theming covers the legacy LMS and Studio pages, and the micro-frontends expose frontend plugin slots and configuration that let you change styles, logos and some page content without editing core code. The harder part is ownership over time. Every Open edX named release changes templates, styles and frontend components, so your team must retest branding after each upgrade and keep a record of what was changed and why. Ask whether you have someone who can read the edx-platform and MFE code, run Tutor locally, and own a staging environment. If the answer is no for any of these, a fixed-scope partner project can cover the initial build and documentation, and you can decide later whether to take over maintenance.
What does our team need to provide for an Open edX branding project?
Your team needs to provide finished design assets, written brand guidelines, one named approver with authority to sign off on each stage, test accounts for each learner and staff role, and access to a staging environment that matches production closely enough to test. Assets usually include logos in vector and raster formats, colour values, typefaces with licence terms, and the page designs for the pages in scope. Without a single approver, feedback arrives from many people and rework grows. Test accounts should cover learners, course teams, administrators and any users who sign in through single sign-on. Confirm early who can grant access to the staging server and how quickly, because waiting on access is a common source of schedule slippage. A written scope should list these inputs with owners and due dates.
How long does a fixed-scope Open edX branding project take?
The duration depends mainly on the number of surfaces in scope, how complete the design work is, and how quickly your approver can respond. A project that covers only the legacy LMS pages and a logo swap moves faster than one that also covers the React micro-frontends, the Studio sidebar, and email templates. Late design changes and multiple reviewers add time more than technical work does. Ask the provider to break the schedule into design review, build, staging review, fixes and handover, and to state which of your inputs each stage depends on. We do not publish a standard duration because each project depends on scope and client readiness. Request the timeline in the written quote and check which dates depend on your team's responses.
Will micro-frontend branding changes break when we upgrade Open edX?
They can, which is why branding should be treated as code that is tested on every upgrade. Open edX states that only the latest named release is supported, so you will move through releases over time, and each release can change the markup, class names, build tooling or plugin slots that your branding depends on. Changes made through supported plugin slots and configuration usually survive upgrades better than changes that override core components or edit built files. Keep branding in version-controlled Tutor plugins or theme packages, write a checklist of visual and functional tests for each page, and run them on staging before each upgrade. Ask the provider how upgrade testing is handled, whether it is in the original scope or in a later support agreement.
Should we edit Open edX core files or use theming hooks and plugin slots?
Use theming hooks, configuration and plugin slots wherever they cover the change, and edit core files only when no supported method exists. Core edits are hard to upgrade because every named release can overwrite them or conflict with them. Tutor supports plugins and hooks, which let you add branding assets, settings and templates in a separate package that you version and deploy with the platform. The Verawood release added new frontend plugin slots, so check the release notes for the version you plan to run to see which slots exist. Where a needed change has no supported hook, the usual options are a small documented override, a change requested upstream, or a custom component. Each option has different maintenance costs, so record the decision in the project documentation.
What should a written quote for Open edX branding include?
A written quote should list the scope in concrete terms: which LMS pages, Studio screens, micro-frontends and emails are covered, and which Open edX release and Tutor version the work targets. It should name each deliverable, such as theme package source, deployment instructions, a style guide and a test report, and state what is excluded. It should show the client inputs and approval points, the stages with their deliverables, and the testing approach for the staging environment. It should also explain what happens with change requests and how upgrades to later named releases are handled, whether within the project or under a separate support agreement. For the wider project, including hosting, organizations, courses and integrations, see the Open edX implementation plan and cost topic, because branding usually depends on those decisions.
Where does branding end and custom Open edX development begin?
Branding changes how the platform looks and how existing screens present content, while custom development adds new behaviour, data flows or integrations. Changing colours, logos, fonts, layouts, page copy and email templates is normally branding work. Adding a new learner dashboard widget, a custom course component, a new report or a change to how grades or enrolment work is development work with its own design, testing and upgrade effort. The line can blur when a brand requirement needs a new frontend component or a backend change to store extra settings. Agree on the boundary in writing before the quote is signed, list any borderline items, and decide who approves a change that crosses the line. Custom components should be scoped separately so their testing and upgrade costs are visible.
Does Open edX branding cover both the legacy LMS and the React micro-frontends?
It can, but the two parts use different methods and need separate testing. The legacy LMS and Studio render pages through Django templates and stylesheets, so branding there depends on theme files and template overrides. The React micro-frontends are built as separate applications, and branding them depends on their styling, configuration and any frontend plugin slots available in your release. A consistent result usually requires both, so your scope should name each page family, such as learner dashboard, course outline, login, instructor dashboard and Studio, and state which layer is changed for each. Ask the provider to test a sample of pages in each layer on staging before the full build, because differences between the two layers are one of the most common causes of inconsistent branding.
How DeployOpen scopes, builds and hands over Open edX branding
DeployOpen plans, implements and documents Open edX theming for the legacy LMS and React micro-frontends inside your own infrastructure. The work is scoped in writing before it starts, built on Tutor's theming and brand package approach, and handed over with the files, configuration and notes your team needs to maintain it.
How we scope
- Inventory every LMS template, Studio view and micro-frontend your learners and course teams actually see.
- Agree which branding changes use theme overrides and which need frontend plugin slots, with no edits to core platform code.
- Confirm the target Open edX named release, since only the latest named release is supported, before design work begins.
- Record scope, deliverables and timelines in a written fixed-scope agreement, with ongoing support offered as a retainer.
How we build
- Package the brand as a Tutor theme or plugin so styling and assets are versioned and reproducible across environments.
- Use frontend plugin slots where the release provides them, keeping custom components separate from upstream MFE source.
- Test branded pages in staging across the LMS, Studio and key MFEs, including mobile layouts, accessibility and email templates.
- Keep secrets, logos and environment-specific settings in Tutor configuration rather than hard-coded in theme files.
How we hand over
- Deliver the theme repository, build steps and a runbook covering how to rebuild and redeploy the branding.
- Document which overrides are custom, which plugin slots they use and what must be re-tested at each release upgrade.
- Walk your platform and course-design teams through editing text, colors and images without touching core code.
- Provide a checklist for verifying branding after an upgrade, so your team can run it without DeployOpen present.
How we support
- Offer retainer support to re-test branding when Tutor or Open edX upgrades change templates or MFE components.
- Review new Open edX named releases and flag theme overrides that will need changes before the next upgrade window.
- Agree response expectations and change handling in the written support scope, not in general terms.
- Ask for the support terms, upgrade testing and handover artifacts to be itemized in your quote.

