API: tokens and Moodle versions
The CSS variables of every Moodle version, light and dark, how to turn them into SCSS or design-tool files, and how to check contrast.
A token is a CSS variable the theme of a Moodle version defines: --bs-primary, --bs-body-bg, the --mds-* of Moodle 5.3. Reading them from here keeps a plugin’s documentation, a Figma kit or a build script in step with the real stylesheet of that version.
What is published
| Address | What it holds |
|---|---|
/api/index.json → versions[] |
Each version with its Bootstrap generation, icon family, support and the links to its tokens and stylesheet |
/api/tokens/<version>.json |
tokens.light and tokens.dark, each a map of variable name to value |
/moodle/<version>/boost.css |
The stylesheet of that version, scoped under .ds-<version> so several can live in one page |
<version> is v53, v45 or v41. Moodle 5.3 has about 500 variables per mode; 4.x versions have far fewer, because Bootstrap 4 compiles its colours into the classes. Dark exists from Moodle 5.x; the 4.x files have an empty dark.
Read a token
const root = 'https://moodle-design.didactika.org';
const v53 = await (await fetch(root + '/api/tokens/v53.json')).json();
console.log(v53.version.label); // "Moodle 5.3 LTS"
console.log(v53.tokens.light['--bs-primary']);
console.log(v53.tokens.dark['--bs-body-bg']);
The families of variables
| Prefix | What it holds |
|---|---|
--bs-* |
Bootstrap: colours, body, borders, fonts, shadows, radii |
--bs-*-rgb |
The same colours as channels, for rgba(var(--bs-primary-rgb), .2) |
--bs-*-bg-subtle, -border-subtle, -text-emphasis |
The tones Bootstrap 5.3 derives for each role |
--mds-* |
Moodle 5.3’s own design system (typography, spacing, colour) |
--primary, --secondary… |
Moodle’s older names, still defined |
Generate SCSS for a tool
const entries = Object.entries(v53.tokens.light).filter(([name]) => name.startsWith('--bs-'));
const scss = entries.map(([name, value]) => `$${name.slice(2)}: ${value};`).join('\n');
Generate a file for a design tool
A set of tokens in the format that Figma plugins and Style Dictionary read ({ "name": { "value": … } }):
const toTokens = (map) => Object.fromEntries(
Object.entries(map)
.filter(([name]) => name.startsWith('--bs-') && !name.endsWith('-rgb'))
.map(([name, value]) => [name.slice(5), {value, type: /^#|^rgb/.test(value) ? 'color' : 'other'}]),
);
const file = {light: toTokens(v53.tokens.light), dark: toTokens(v53.tokens.dark)};
Check contrast with the real colours
const luminance = ([r, g, b]) => {
const f = (x) => { const v = x / 255; return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; };
return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
};
const rgb = (hex) => [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16));
const ratio = (a, b) => { const [x, y] = [luminance(rgb(a)), luminance(rgb(b))].sort((p, q) => q - p); return (x + 0.05) / (y + 0.05); };
console.log(ratio(v53.tokens.light['--bs-primary'], '#ffffff').toFixed(2)); // 4.5 or more
The colours of the Didactika theme are not tokens of Moodle
The palette of the Didactika theme (/api/brand.json) is applied on top of Moodle’s variables. A plugin never hard-codes a hex value from it: it uses the Bootstrap variable (var(--bs-primary)) and the palette arrives with the theme. See the page “Didactika theme”.
Check a version before you rely on it
The support field of each version says whether it is current, LTS or legacy, in both languages. Read it when a guide tells people which versions to test; the matrix of a CI should include the two ends of the supported range and the LTS in between.
UI