Moodle Theme Development: Child Themes, the Upgrade Trap, and When to DIY
For almost everyone, this means a Boost child theme — not a from-scratch build. What theming can change, the upgrade trap that breaks themes, real costs, and the free DIY path.
The short version
Key takeaways
- ✓ A Boost child theme is the default-right choice: it inherits Boost's accessibility, responsive layout and security patches, and you override only what you touch.
- ✓ Themes control presentation only: SCSS/CSS (styling) and Mustache (HTML structure). Core behaviour and logic live in PHP and plugins, and no theme can change them.
- ✓ The upgrade trap: fully custom or cloned themes miss upstream fixes and break when Moodle changes core templates (a new major release lands roughly every 6 months, in April and October). Every Mustache template you override becomes a file you now maintain.
- ✓ Branding (logo, colours, fonts, login page) is cheap, safe and usually no-code. A real UX or navigation change means template overrides plus real testing.
- ✓ Costs, in effort terms: no-code DIY is free; a studio child theme is a light, well-scoped project; bespoke custom themes are a substantial engagement; freelance rates vary widely by region and seniority; premium theme licences are sold on annual or one-time terms.
- ✓ You may not need to hire at all: Boost's admin settings plus the Raw SCSS box, or the free GPLv3 Boost Union theme, cover most branding jobs without a single file.
At a glance
The four approaches, compared
| Approach | What you can change | Upgrade safety | Effort & expertise | Best for |
|---|---|---|---|---|
| Boost admin settings + Raw SCSS | Logo, brand colour, preset, fonts, custom CSS/SCSS | Very safe - settings survive upgrades | Free | Branding and quick wins |
| Boost Union (free theme) | All of the above plus menus, footers, login, layout options via UI | Safe - maintained plugin that follows Boost | Free (GPLv3) | Most institutions on a budget |
| Boost child theme | SCSS variables plus selective Mustache overrides | Good - inherits Boost; overrides need re-testing | DIY free; a light project to hire | Custom branding plus light layout |
| Fully custom theme | Anything in presentation | Risky - misses upstream fixes, breaks on core template changes | Substantial — weeks to months | Bespoke UX and white-label products |
What theming can and cannot change
Moodle's front end is three layers, and a theme only reaches two of them.
- PHP = logic and content (what a page does). This is core and plugins; a theme cannot touch it.
- Mustache = the HTML structure of a page. You can override any template safely, without editing core.
- SCSS/CSS = the visual styling. This is where most real theming happens.
- So a theme CAN change: colours, fonts, spacing, logos, login page, navigation layout, dashboard look, course layout markup.
- A theme CANNOT change: how activities work, permissions, grading, enrolment, or any behaviour. Those are plugins or core PHP. If you need new functionality, that is plugin development, not theming.
How to choose your approach
Start at the top of this list and only move down when a setting genuinely can't do the job.
- No-code, in the admin panel: switch to Boost, then set preset, brand colour, and logo in Site administration > Appearance > Themes > Boost, and paste tweaks into the Raw SCSS box. Survives upgrades.
- Free configurable theme: install Boost Union (GPLv3, from Moodle an Hochschulen) for far more UI settings - custom fonts, menus, footers, login layout - all through admin, no files.
- Boost child theme (light code): a new folder in /theme with $THEME->parents = ['boost'], a version.php and a scss/ folder. Change SCSS variables first; override a handful of Mustache templates only if you must.
- Fully custom theme: maximum control, maximum maintenance. Reserve it for bespoke UX or white-label products, and budget for re-testing every release.
Anatomy of a Boost child theme
It is smaller than people expect - often a dozen lines plus a stylesheet.
- config.php: $THEME->name, $THEME->parents = ['boost'], and $THEME->scss = 'default' (which compiles scss/default.scss in your theme).
- version.php: component name (theme_yourname), version, and requires (the minimum Moodle version).
- scss/ folder: your SCSS. Override Bootstrap/Boost variables (brand colour, fonts, radii) here - this alone covers most branding. Note the SCSS file does not inherit from the parent; import what you need.
- prescsscallback / extrascsscallback (in lib.php): functions that inject SCSS before or after your main file (used to wire admin colour settings into the compile).
- templates/[component]/[name].mustache: drop a copy of a core template here to override it - for example templates/core/columns2.mustache to change a page layout. Only override what you truly need.
- lang/en/theme_yourname.php: strings for any settings you expose. Never edit the Boost theme itself - that is what breaks on upgrade.
The upgrade-safety trap
This is the single most expensive mistake in Moodle theming.
- Moodle ships a new major version roughly every 6 months (April and October; the current line is 5.2, with 5.3 LTS due October 2026), and each can change core Mustache templates and layouts.
- A Mustache template you override is frozen at the moment you copied it. When core moves on, your copy silently goes stale - a broken layout, a missing button, or a lost accessibility fix.
- Real example: Moodle 3.6 added a required renderer callback to core layout templates, so child themes that had copied columns1/columns2.mustache lost the message drawer until they were updated. Similar breakage recurs across major releases.
- A child theme mitigates this because it inherits everything you did NOT override - so the fewer templates you copy, the fewer break.
- Custom CSS/SCSS entered in theme settings is safe: it is a stored setting, not a file, and survives upgrades.
- Cloned or fully custom themes are the worst case: they miss every upstream fix and must be re-audited against each new version. Keep a written list of every template you override so you can re-test them each release.
Accessibility (WCAG) and mobile - what you inherit and what you can break
Boost gives you a lot for free; sloppy overrides take it away.
- Moodle LMS (recent versions), Workplace and the Moodle App hold WCAG 2.2 Level AA accreditation, and the default Boost theme is built to that standard.
- Out of the box Boost provides skip-navigation links, correct ARIA landmarks (header, main, nav, aside, footer), a fully responsive layout, no content loss at 200% zoom, and 4.5:1 text contrast.
- Your brand colours can quietly fail contrast - always check the 4.5:1 ratio, not just whether it looks nice.
- Overriding a Mustache template can strip ARIA attributes or skip links if you copy an old version or delete markup - test with a keyboard and a screen reader.
- US public bodies: ADA Title II now points at WCAG 2.1 AA as the practical bar, so accessibility is increasingly a compliance issue, not a nicety.
- Always test on a real phone and in the Moodle App, not just a narrow browser window.
Branding vs a true UX change
Be honest with yourself about which one you actually want - the cost gap is large.
- Branding = logo, brand colour, fonts, favicon, login page background. Cheap, safe, mostly no-code, no upgrade risk.
- UX change = navigation structure, dashboard layout, course-format markup, custom blocks. Requires Mustache overrides and sometimes companion plugins.
- Most 'we need a custom theme' requests are actually branding requests that Boost settings or Boost Union already handle.
- If the change is about what users can DO (not what they see), it is a plugin, not a theme - budget and plan accordingly.
The honest numbers
What it costs
| Item | Effort & expertise | What drives it |
|---|---|---|
| No-code (Boost admin settings or Boost Union) | Free | Your own time. Covers logo, brand colour, preset, fonts, login page, and a Raw SCSS box. |
| DIY Boost child theme | Free (your time) | A config.php, version.php, a scss/ folder of variables, and maybe a couple of Mustache overrides. A weekend for a comfortable developer. |
| Studio child theme (e.g. Sternfast) | Light — a well-scoped project | Branded Boost child theme with colours, fonts, login and light layout work; extra scope quoted after a free scoping call. |
| Freelance / agency custom theme | Substantial — weeks to months | Number of overridden templates, bespoke layouts, plugin-integrated UI, and accessibility audit. Intermediate institutional themes are typically a multi-week engagement. |
| Freelance developer rate | Varies widely | Region and seniority drive it: highest in North America/Oceania and Western Europe, lower in Eastern Europe/Latin America and South Asia/Africa. |
| Premium theme licence (RemUI, Moove, etc.) | Annual or one-time licence | Support, update entitlement and white-label rights. Single-site licences are sold on a modest annual subscription (e.g. Edwiser RemUI); many also sell a one-time/lifetime licence (e.g. Moove). Often the cheapest route to a polished look. |
| Ongoing maintenance / upgrade testing | Ongoing subscription | Often bundled into managed hosting on a straightforward monthly subscription. Scales with how many custom template overrides must be re-tested on each Moodle release; a clean child theme needs almost none. |
These effort and expertise levels reflect current 2025–2026 conditions and vary with scope; treat them as planning guidance, and get a fixed quote after a free scoping call.
You probably don't need to hire anyone (if it's branding). Switch to Boost, then in Site administration > Appearance > Themes > Boost set your preset, brand colour and logo, and paste any tweaks into the Raw SCSS box - no files, no code, and it survives upgrades. Want more (custom fonts, menus, footers, login layout) without code? Install the free, GPLv3 Boost Union theme and configure it entirely through admin settings. Ready for a little code? A Boost child theme is genuinely small: a new folder under /theme, a roughly ten-line config.php with $THEME->parents = ['boost'], a version.php, and a scss/ folder - change SCSS variables first, and override a Mustache template only when a setting truly can't do it. Consider hiring when you need bespoke layouts, plugin-integrated UI, a formal WCAG audit, multi-tenant/white-label, or you simply can't afford to re-test template overrides across Moodle's twice-a-year releases.
Where to start
- Before touching any code, switch to Boost and set your preset, brand colour and logo in Site administration > Appearance > Themes > Boost.
- Try the free Boost Union theme (GPLv3) - it adds fonts, menus, footers and login options entirely through admin settings, and covers most institutions without a line of code.
- If you truly need code, create a child theme: a new folder in /theme, a config.php with $THEME->parents = ['boost'], a version.php, and a scss/ folder. Never edit Boost itself.
- Change SCSS variables (brand colours, fonts, spacing) in your scss/ folder or via prescsscallback before you consider overriding any template.
- Override Mustache templates only as a last resort, one at a time, into templates/[component]/[name].mustache - and write down every template you copy so you can re-test it later.
- Test at 200% zoom, on a real phone and in the Moodle App, and with keyboard-only navigation. Re-run these checks after every Moodle upgrade.
If you'd rather hand it off
If your change is really branding, Boost or the free Boost Union theme will get you there — start there. If you do need a proper child theme or bespoke work, we build them as a well-scoped project, quoted after a free scoping call, upgrade-safe. Either way, don't pay for a custom theme you don't need.
References & further reading
- Theme plugins - Moodle Developer Resources
- Creating a theme based on Boost - MoodleDocs
- SCSS - MoodleDocs
- Moodle releases and support schedule
- Moodle accessibility (WCAG 2.2 AA)
- Boost Union (free theme, GitHub)
- Moodle end-of-life dates
On Sternfast
Questions people ask
Do I need to know how to code to change my Moodle theme?
No. Logo, brand colour, preset, fonts and a custom SCSS/CSS box all live in Site administration > Appearance. The free Boost Union theme adds far more UI settings. You only need code for genuinely custom layouts.
Should I build a child theme or a fully custom theme?
Almost always a Boost child theme. It inherits Boost's accessibility, responsive layout and security patches and overrides only what you change, so it survives Moodle upgrades far better than a from-scratch theme.
Why did my theme break after a Moodle upgrade?
Usually because it overrides a core Mustache template or layout that Moodle changed in the new version. Every template you copy is frozen at copy time, so when core moves your copy goes stale. Keep overrides minimal and re-test each release.
Can a theme change how Moodle works, not just how it looks?
No. Themes control presentation (SCSS plus Mustache HTML). Behaviour, permissions and features are core PHP and plugins. If you need new functionality, that is plugin development, not theming.
How much does a custom Moodle theme cost?
DIY is free. A branded child theme from a studio is a light, well-scoped project; bespoke custom themes are a substantial engagement that scales with how many templates and layouts change. Freelance rates vary widely by region and seniority, and premium theme licences are sold on annual or one-time terms.