Will Moodle ever use Rust? Not in core, but in your tools
Moodle will not be rewritten in Rust. Rust is reaching it through tooling instead: what JS, Python and PHP switched to, and what plugin devs can use today.
No. Moodle itself will not be rewritten in Rust, and nobody serious is asking for it. But Rust is already arriving in the way it arrived everywhere else in web development: through the tools that lint, format, type-check and bundle the code, not through the application.
That second part is the interesting one. JavaScript and Python developers changed most of their toolchain between 2023 and 2026. PHP is starting to. Moodle’s own toolchain has barely moved, and Moodle HQ has an open issue saying so.
Why will Moodle core never be rewritten in Rust?
Three reasons, any one of which is enough.
The codebase. Moodle has been developed since before the 1.0 release in 2002, and the moodle/moodle repository on GitHub shows more than 123,000 commits.1 As our architecture history shows, Moodle has never been thrown away, only rebuilt in place. Even the 2.0 rebuild of a few core layers took more than two and a half years between major releases.
The plugins. The plugin directory passed 2,000 open-source plugins back in 2022,2 and every one of them is PHP that calls Moodle’s PHP APIs. Then add the private plugins every institution and agency keeps in its own git. A Rust core would need either a PHP compatibility layer for all of that, which defeats the point, or a full rewrite of the ecosystem, which will not happen.
The hosting. Moodle 5.3 needs 64-bit PHP 8.3 or 8.4 and a supported database. The release notes list PHP and a database, nothing else.3 It runs on any host that runs PHP, which is why stats.moodle.org lists more than 145,000 registered sites in 235 countries.4 Moodle HQ even treats Node.js as something production sites must not need: Moodle ships pre-built JavaScript because, in the words of one HQ issue, “we do not require JS on production sites, and have no way of building on them”.5 A Rust core would turn every Moodle install into a compiled binary to build, ship and support per platform. That is the opposite of how Moodle is deployed.
There is also the general lesson. Joel Spolsky’s essay on Netscape called rewriting code from scratch “the single worst strategic mistake that any software company can make”. He wrote it in 2000, when Netscape had gone almost three years without a major release.6 You do not need to agree with every word to see that Moodle, with 24 years of behaviour baked into it, is the textbook case for not trying.
Where has Rust actually won?
In tooling. The pattern is the same in every language: a slow tool written in the language it serves gets replaced by a native one that does the same job, often with the same config format and the same rules, many times faster. The application code does not change. The developer’s wait does.
| Tool | Language | Replaces | Project’s own claim |
|---|---|---|---|
| SWC | Rust | Babel | ”20x faster than Babel on a single thread”7 |
| Biome | Rust | Prettier, ESLint | About 35x faster than Prettier in its homepage benchmark8 |
| Oxlint (oxc) | Rust | ESLint | ”around 50~100 times faster than ESLint”9 |
| Rolldown in Vite 8 | Rust | esbuild + Rollup inside Vite | ”10-30x faster than Rollup”10 |
| Turbopack | Rust | webpack in Next.js | 2-5x faster production builds11 |
| Rspack | Rust | webpack | Webpack loader compatible12 |
| Ruff | Rust | Flake8, Black, isort | ”10-100x faster”13 |
| uv | Rust | pip and friends | ”10-100x faster than pip”14 |
All the speed numbers are the projects’ own benchmarks, not ours. Treat them as direction, not as a promise for your codebase.
What matters more than the numbers is that these are now defaults, not experiments. Next.js 16 made Turbopack “the default bundler for all new Next.js projects” in October 2025.11 Vite 8, released on 12 March 2026, replaced its two bundlers, esbuild for development and Rollup for production, with Rolldown.10 Oxlint reached 1.0 in June 2025 with Shopify, Airbnb and Mercedes-Benz named as users.9 Biome is on version 2.6.8
Python went the same way. Astral’s Ruff replaces Flake8, Black and isort with one Rust binary, and uv does the same for pip and virtualenv management.
Is TypeScript part of the same story?
Yes, with one correction: it is not Rust. Microsoft announced in March 2025 that it was porting the TypeScript compiler to Go, under the codename Corsa, to “reduce most build times by 10x”.15 TypeScript 7.0 shipped on 8 July 2026 as “a 10x faster native port of TypeScript”.16
The reasoning is the same as Rust’s wins: the tool was written in the language it serves, and that language is slow for compilers. The method is worth noting too. Microsoft ported the existing codebase rather than designing a new one, which is the opposite of the Netscape mistake. And there is a catch that will matter below: TypeScript 7.0 “does not ship with an API”,16 so tools that call the compiler programmatically have to stay on TypeScript 6 for now.
Is anything like this happening in PHP?
Yes, and it is called Mago. It is a linter, formatter and static analyzer for PHP in one binary, written in Rust by Carthage Software, under MIT or Apache-2.0.17 It names Clippy, oxc and Hakana as inspiration, and PHP-CS-Fixer, Psalm, PHPStan and PHP_CodeSniffer as the tools that came before it.
Its status as of late October 2026:
- Stable since December 2025. Version 1.0.0 shipped on 20 December 2025 with 135 lint rules, a formatter, a rewritten analyzer, architectural boundary checks called Guard, and baseline support for adopting it on old code.18
- Moving fast. Version 1.59.0 came out on 25 October 2026, the fifth minor release that month.19
- Adoption is early. The repository has about 3,500 stars, and lists sponsors, not users.17 It reads PHPStan and Psalm annotations, so it can run next to them.20
- The speed claim. The 1.0.0 notes put Mago at about 3.9 seconds to analyze WordPress, against 45.5 seconds for Psalm and 120.4 seconds for PHPStan.18 Again, the project’s own numbers.
The other Rust PHP project worth knowing is ext-php-rs, bindings for “build PHP extensions natively in Rust”.21 It is at version 0.16, so pre-1.0. It is a way to put Rust inside a PHP runtime, not a reason to put it inside Moodle.
What does Moodle’s toolchain look like today?
Read package.json on the 5.3 stable branch and it is a Node toolchain from a few years ago, plus one new path for React.22
| Job | Tool in core | Written in |
|---|---|---|
| Task runner | Grunt ^1.6.1 | JavaScript |
| AMD and ES module transpiling | Babel 7.17.5, run through Rollup | JavaScript |
| JS linting | ESLint ^8.56.0 | JavaScript |
| CSS linting | stylelint ^15.11.0 | JavaScript |
| SCSS | Dart Sass ^1.58.3 | Dart, compiled to JS |
| React and TypeScript bundles | esbuild ^0.25.0 | Go |
| Type declarations | TypeScript ^5.7.3 API | TypeScript |
| JS tests | Jest | JavaScript |
Two details stand out. Babel is pinned to an exact version, and the Grunt amd task runs ESLint, then Rollup with a Babel transform, then a custom amdtypes step that uses the TypeScript compiler API to write .d.ts files.23 That last step is exactly the kind of tool that cannot move to TypeScript 7 yet, because 7.0 has no API.
The second detail is the more hopeful one. The React path added in 5.2 does not go through Babel. Moodle’s docs say it provides “React TypeScript component builds using esbuild integrated with Grunt”, with grunt react and grunt react:watch using esbuild’s native watch mode.24 So Moodle has already adopted one native build tool. It is Go, not Rust, but it is the same decision every other ecosystem made.
Has Moodle HQ talked about leaving Grunt?
Twice, and neither issue has produced a change.
- MDL-62513, “Look at alternatives to Grunt” (2018). It said Grunt “has become slow, and cumbersome, and is not ideally suited to our needs any more”, and suggested webpack or gulp. It was closed as Deferred in August 2025, meaning the LMS teams will not work on it in the foreseeable future.25
- MDL-80762, “Consider future of Grunt and Moodle CLI tooling” (January 2024). Opened by Andrew Lyons of Moodle HQ, it is still open. It says Grunt’s ESM support is a problem as packages drop CommonJS, rules out the usual bundlers because “what they do is take a lot of inputs, and compile them into a single output”, and floats writing Moodle’s own tooling. A follow-up comment suggests npm scripts, as Bootstrap uses.5
The bundler argument is fair. Moodle builds one output file per source module, per component, and a single-bundle tool does not fit that. But it is an argument against Vite or webpack as a build system, not against faster linters, formatters or transpilers inside whatever runs the tasks. A tracker search for Biome, Oxlint, SWC, Rolldown and Mago finds one relevant hit. While adding Jest for React components in MDL-87781 (fixed in 5.3), a developer hit a clash with the Babel version core pins and listed @swc/jest as a way around it.26 The 5.3 branch shipped with ts-jest instead.22 So the Rust option has been seen, and set aside.
Earlier speed work was about Grunt’s own overhead: MDL-67449, “Grunt amd:dist very slow”, fixed slow file globbing in 3.9.27
Why does this matter for plugin CI?
Because CI is where the slow tools add up. moodle-plugin-ci install clones Moodle, configures a database and installs your plugin into it; the grunt command then runs the amd, yui, gherkinlint and stylelint tasks by default.28 The standard workflow runs all of that once per row of a PHP and database matrix, before PHPUnit and Behat even start. We covered what each step checks in our testing post.
None of those steps is slow because of one bad tool. They are slow because each job rebuilds the world. A faster linter will not fix Behat. It does let you fail in seconds on the mistakes that are cheapest to catch, before you pay for the matrix.
What can a plugin developer use today?
Without waiting for HQ, and without breaking the checks HQ runs:
- Run Mago next to moodle-cs, not instead of it. Install it with
composer require --dev carthage-software/mago,29 generate a baseline for existing code, and runmago analyzeandmago lintlocally or in a pre-commit hook. Keepphpcswith moodle-cs as the gate, because that is what moodle-plugin-ci and reviewers check. - Use TypeScript 7 for type-checking only. If your plugin has React components under
js/esm/src, a separatetsc --noEmitwith 7.0 is a fast check. Do not change the TypeScript version core’spackage.jsonuses, sinceamdtypesdepends on the compiler API that 7.0 lacks. - Add a fast job before the matrix. Moodle-plugin-ci has
--no-initto skip PHPUnit and Behat setup.28 One cheap job for lint, Mago and type checks, with the full matrix only after it passes, saves CI minutes on every broken push. - Run Oxlint or Biome in your editor, not in CI. They give instant feedback on obvious JavaScript mistakes. Moodle’s ESLint config is still the one
gruntenforces, so treat the fast tool as a first pass and let Grunt have the final word. - Use uv for any Python scripts around your plugin, such as data migration or reporting helpers. It is the easiest of these to adopt.
The developer experience post argued Moodle most needs official static analysis. Mago does not change that, but it does make running an analyzer on every save cheap enough that there is no excuse not to. And for the React side, our post on React in Moodle covers where esbuild fits.
DevLMS builds custom Moodle plugins, and the official Moodle checks are the standard every plugin we ship has to pass.
Sources
-
GitHub, moodle/moodle, main branch, checked 31 October 2026. ↑
-
Moodle, The Moodle Plugins directory surpasses 2000 plugins!. ↑
-
Moodle HQ, Moodle 5.3 release notes. ↑
-
Moodle, Moodle statistics, checked 31 October 2026. ↑
-
Moodle Tracker, MDL-80762: Consider future of Grunt and Moodle CLI tooling. ↑ ↑
-
Joel Spolsky, Things You Should Never Do, Part I. ↑
-
Biome, biomejs.dev. ↑ ↑
-
Oxc, Oxlint v1.0 Stable. ↑ ↑
-
Vite, Vite 8.0 is out!. ↑ ↑
-
Vercel, Next.js 16 and Turbopack. ↑ ↑
-
Astral, uv on GitHub. ↑
-
Microsoft, A 10x Faster TypeScript. ↑
-
Microsoft, Announcing TypeScript 7.0. ↑ ↑
-
GitHub, carthage-software/mago, checked 31 October 2026. ↑ ↑
-
GitHub, Mago 1.0.0 release notes. ↑ ↑
-
GitHub, Mago releases. ↑
-
Mago, Documentation. ↑
-
docs.rs, ext-php-rs. ↑
-
Moodle HQ, React build tools (5.2). ↑
-
Moodle Tracker, MDL-62513: Look at alternatives to Grunt. ↑
-
Moodle Tracker, MDL-87781: Integrate proof of concept JavaScript unit testing code for testing future react components. ↑
-
Moodle Tracker, MDL-67449: Grunt amd:dist very slow. ↑
-
Moodle HQ, moodle-plugin-ci CLI commands. ↑ ↑
-
Mago, Installation. ↑
Need a Moodle plugin built or rescued?
Tell the scoping assistant what you need. You get a fixed price and a timeline in a few minutes, and an engineer reviews it within one business day.
Get a fixed quote