# adityaboghara/better-moodle architecture

> Architecture diagram of the GitHub repository adityaboghara/better-moodle, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-21). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/adityaboghara/better-moodle
- Repository: https://github.com/adityaboghara/better-moodle

## Overview

1. **What this repo is**
   Better-Moodle is a client-side **userscript** that runs in the browser on Moodle pages. There is no central backend for the product itself; the script injects UI, patches page behavior, and stores user preferences locally.

2. **Top-level runtime split**
   The main runtime is under `src/`, with a small set of entrypoints like `core.tsx`, `cleanupStorage.ts`, `migrateStorage.ts`, and `unsupportedBrowserCheck.tsx`. The core runtime is what users normally get; the other entrypoints handle storage maintenance and browser compatibility warnings.

3. **Core orchestration**
   `src/core.tsx` is the bootstrapping layer. It ties together feature registration, university-specific configuration, i18n, settings, update checks, and global fixes before individual features run. `src/core/globalFixes` contains patches that apply broadly across Moodle, independent of a specific feature toggle.

4. **Feature-based architecture**
   Most functionality is organized as independent modules in `src/features/*`. Each feature is typically self-contained, with its own entry file, styles, and often its own translations. This lets the build include only the features relevant to the selected university/configuration and lets users enable/disable them from settings.

5. **Shared UI and infrastructure**
   `src/_lib` holds the common building blocks: reusable React components, drawers/modals, settings controls, DOM helpers, network helpers, storage wrappers, template helpers, and Moodle-specific string/semver/time utilities. This is the internal platform layer that features build on.

6. **State and persistence**
   User preferences and migration logic are handled through `TempStorage`, `migrateStorage.ts`, and `cleanupStorage.ts`. The script persists settings in browser storage, migrates older data formats, and can clean up obsolete keys. That means feature state lives entirely on the client side.

7. **University-specific boundaries**
   The repo is clearly split by institution. `configs/` contains per-university and global JSON config, while `src/fixes/cau` and `src/fixes/uzl` contain institution-specific fixes. The README also shows separate distributed builds/downloads for CAU Kiel and Universität zu Lübeck, so the build output is university-targeted rather than one generic bundle.

8. **External Moodle integration**
   The `types/require.js` tree shows strong coupling to Moodle’s AMD/RequireJS modules and templates. Better-Moodle does not replace Moodle; it extends it by consuming Moodle’s internal modules, DOM structure, and templates, which is why those ambient typings are a major architectural boundary.

9. **Localized content and templating**
   `src/i18n` contains the language packs and formatting helpers, while many feature folders also have their own `i18n` subtrees. Mustache templates and SCSS modules are used where features need Moodle-compatible markup or scoped styling. The result is a localized, theme-aware userscript rather than a single-language overlay.

10. **Feature-specific external data flows**
    Some features integrate third-party or campus services. Examples include weather providers (`open-meteo`, `openweathermap`, `visualcrossing`, `wttr.in`), canteen/menu parsing, NINA emergency integration, and event/semester data from `data/*.json`. These modules adapt external data into the script’s UI and settings model.

11. **Auxiliary parser/runtime**
    The `ics-parser/` directory is a separate TypeScript worker-style component with its own Wrangler config. It indicates a distinct parsing runtime for calendar/ICS-style data, separate from the browser userscript bundle.

12. **Build and distribution pipeline**
    The repo uses a custom Vite-based toolchain in `tooling/` to assemble the userscript, resolve features/fixes, process SCSS and Mustache, inject legacy/polyfill behavior, and format post-build output. Release automation is handled via GitHub Actions and Release Please, which produce the downloadable `.user.js` artifacts referenced in the README.

13. **Testing and quality gates**
    Tests live under `__tests__` and use Vitest plus browser-oriented helpers/Puppeteer. CI workflows cover build, test, config validation, icon generation, release automation, and download tracking, so the repository is structured as a packaged extension-like artifact with strong build-time verification.

Main entry points: [`src/core.tsx`](https://github.com/adityaboghara/better-moodle/blob/main/src/core.tsx) (Core), [`tooling/framework.ts`](https://github.com/adityaboghara/better-moodle/blob/main/tooling/framework.ts) (Tooling), [`src/features/courses/index.ts`](https://github.com/adityaboghara/better-moodle/blob/main/src/features/courses/index.ts) (Courses), [`src/_lib/TempStorage.ts`](https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/TempStorage.ts) (TempStorage)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime"]
  node_src_core["Core<br/>bootstrap userscript<br/>[core.tsx]"]
  node_src_settings["Settings UI<br/>settings modal<br/>[settingsModal.tsx]"]
  node_src_migrate["Migrate Storage<br/>storage migration<br/>[migrateStorage.ts]"]
  node_src_cleanup["Cleanup Storage<br/>storage cleanup<br/>[cleanupStorage.ts]"]
  node_src_browsercheck["Browser Check<br/>compat warning"]
  node_src_globalfixes["Global Fixes<br/>cross-cutting patches<br/>[index.ts]"]
end

subgraph group_platform["Shared Platform"]
  node_lib_feature["Feature Base<br/>feature framework<br/>[Feature.tsx]"]
  node_lib_storage["TempStorage<br/>persistence wrapper<br/>[TempStorage.ts]"]
  node_lib_ui["Shared UI<br/>react components<br/>[Components.tsx]"]
  node_lib_dom["DOM Helpers<br/>dom utilities<br/>[DOM.ts]"]
  node_lib_require["Moodle AMD<br/>moodle interop<br/>[require.js.ts]"]
  node_lib_i18n["i18n Core<br/>localization<br/>[i18n.ts]"]
end

subgraph group_features["Features"]
  node_features_courses["Courses<br/>feature bundle<br/>[index.ts]"]
  node_features_general["General<br/>feature bundle<br/>[index.ts]"]
  node_features_dashboard["Dashboard<br/>feature bundle<br/>[index.ts]"]
  node_features_messages["Messages<br/>feature bundle<br/>[index.ts]"]
  node_features_weather["Weather<br/>feature bundle<br/>[index.tsx]"]
  node_features_speiseplan["Canteen<br/>feature bundle<br/>[index.tsx]"]
  node_features_nina["NINA<br/>feature bundle<br/>[index.tsx]"]
  node_features_navmarquee["Marquee<br/>feature bundle<br/>[index.ts]"]
  node_fixes_cau["CAU Fixes<br/>institution fixes<br/>[loginDivider.tsx]"]
  node_fixes_uzl["UZL Fixes<br/>institution fixes<br/>[zensus.ts]"]
end

subgraph group_build["Build"]
  node_tooling_vite["Tooling<br/>build pipeline<br/>[framework.ts]"]
  node_ics_parser["ICS Parser<br/>aux runtime<br/>[index.ts]"]
end

subgraph group_boundaries["External Boundaries"]
  node_types_require["Require Types<br/>ambient typings<br/>[require.d.ts]"]
end

node_src_core -->|"registers"| node_lib_feature
node_src_core -->|"applies"| node_src_globalfixes
node_src_core -->|"loads"| node_lib_i18n
node_src_core -->|"reads/writes"| node_lib_storage
node_src_core -->|"opens"| node_src_settings
node_src_core -->|"enables"| node_features_courses
node_src_core -->|"enables"| node_features_general
node_src_core -->|"enables"| node_features_dashboard
node_src_core -->|"enables"| node_features_messages
node_src_core -->|"enables"| node_features_weather
node_src_core -->|"enables"| node_features_speiseplan
node_src_core -->|"enables"| node_features_nina
node_src_core -->|"enables"| node_features_navmarquee
node_src_core -->|"targets"| node_fixes_cau
node_src_core -->|"targets"| node_fixes_uzl
node_src_migrate -->|"migrates"| node_lib_storage
node_src_cleanup -->|"cleans"| node_lib_storage
node_src_browsercheck -->|"detects"| node_lib_require
node_features_courses -->|"patches"| node_lib_dom
node_features_courses -->|"renders"| node_lib_ui
node_features_messages -->|"patches"| node_lib_dom
node_features_weather -.->|"fetches"| node_tooling_vite
node_features_speiseplan -.->|"fetches"| node_tooling_vite
node_features_nina -.->|"fetches"| node_tooling_vite
node_tooling_vite -->|"validates"| node_types_require
node_tooling_vite -->|"bundles"| node_ics_parser

click node_src_core "https://github.com/adityaboghara/better-moodle/blob/main/src/core.tsx"
click node_src_settings "https://github.com/adityaboghara/better-moodle/blob/main/src/settingsModal.tsx"
click node_src_migrate "https://github.com/adityaboghara/better-moodle/blob/main/src/migrateStorage.ts"
click node_src_cleanup "https://github.com/adityaboghara/better-moodle/blob/main/src/cleanupStorage.ts"
click node_src_browsercheck "https://github.com/adityaboghara/better-moodle/blob/main/src/unsupportedBrowserCheck.tsx"
click node_src_globalfixes "https://github.com/adityaboghara/better-moodle/blob/main/src/core/globalFixes/index.ts"
click node_lib_feature "https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/Feature.tsx"
click node_lib_storage "https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/TempStorage.ts"
click node_lib_ui "https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/Components.tsx"
click node_lib_dom "https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/DOM.ts"
click node_lib_require "https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/require.js.ts"
click node_lib_i18n "https://github.com/adityaboghara/better-moodle/blob/main/src/i18n/i18n.ts"
click node_features_courses "https://github.com/adityaboghara/better-moodle/blob/main/src/features/courses/index.ts"
click node_features_general "https://github.com/adityaboghara/better-moodle/blob/main/src/features/general/index.ts"
click node_features_dashboard "https://github.com/adityaboghara/better-moodle/blob/main/src/features/dashboard/index.ts"
click node_features_messages "https://github.com/adityaboghara/better-moodle/blob/main/src/features/messages/index.ts"
click node_features_weather "https://github.com/adityaboghara/better-moodle/blob/main/src/features/weather/index.tsx"
click node_features_speiseplan "https://github.com/adityaboghara/better-moodle/blob/main/src/features/speiseplan/index.tsx"
click node_features_nina "https://github.com/adityaboghara/better-moodle/blob/main/src/features/nina/index.tsx"
click node_features_navmarquee "https://github.com/adityaboghara/better-moodle/blob/main/src/features/navbarMarquee/index.ts"
click node_fixes_cau "https://github.com/adityaboghara/better-moodle/blob/main/src/fixes/cau/loginDivider.tsx"
click node_fixes_uzl "https://github.com/adityaboghara/better-moodle/blob/main/src/fixes/uzl/zensus.ts"
click node_tooling_vite "https://github.com/adityaboghara/better-moodle/blob/main/tooling/framework.ts"
click node_ics_parser "https://github.com/adityaboghara/better-moodle/blob/main/ics-parser/index.ts"
click node_types_require "https://github.com/adityaboghara/better-moodle/blob/main/types/require.d.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_src_core,node_src_settings,node_src_migrate,node_src_cleanup,node_src_browsercheck,node_src_globalfixes toneBlue
class node_lib_feature,node_lib_storage,node_lib_ui,node_lib_dom,node_lib_require,node_lib_i18n toneAmber
class node_features_courses,node_features_general,node_features_dashboard,node_features_messages,node_features_weather,node_features_speiseplan,node_features_nina,node_features_navmarquee,node_fixes_cau,node_fixes_uzl toneMint
class node_tooling_vite,node_ics_parser toneRose
class node_types_require toneIndigo
```

## Components

### Runtime

Userscript entrypoints and browser-facing boot logic.

- [Core](https://github.com/adityaboghara/better-moodle/blob/main/src/core.tsx): bootstrap userscript · Main startup path that wires config, settings, i18n, fixes, and features. · `src/core.tsx`
- [Settings UI](https://github.com/adityaboghara/better-moodle/blob/main/src/settingsModal.tsx): settings modal · Client-side settings surface for enabling features and preferences. · `src/settingsModal.tsx`
- [Migrate Storage](https://github.com/adityaboghara/better-moodle/blob/main/src/migrateStorage.ts): storage migration · Upgrades persisted user data to newer formats. · `src/migrateStorage.ts`
- [Cleanup Storage](https://github.com/adityaboghara/better-moodle/blob/main/src/cleanupStorage.ts): storage cleanup · Removes obsolete local keys and stale data. · `src/cleanupStorage.ts`
- [Browser Check](https://github.com/adityaboghara/better-moodle/blob/main/src/unsupportedBrowserCheck.tsx): compat warning · Warns when the host browser is unsupported. · `src/unsupportedBrowserCheck.tsx`
- [Global Fixes](https://github.com/adityaboghara/better-moodle/blob/main/src/core/globalFixes/index.ts): cross-cutting patches · Moodle-wide behavior patches applied independently of feature toggles. · `src/core/globalFixes/index.ts`

### Shared Platform

Common UI, storage, i18n, and Moodle integration helpers.

- [Feature Base](https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/Feature.tsx): feature framework · Common registration and lifecycle primitives for features. · `src/_lib/Feature.tsx`
- [TempStorage](https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/TempStorage.ts): persistence wrapper · Browser storage abstraction used for preferences and migrations. · `src/_lib/TempStorage.ts`
- [Shared UI](https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/Components.tsx): react components · Reusable drawers, modals, blocks, settings controls, and related UI pieces. · `src/_lib/Components.tsx`
- [DOM Helpers](https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/DOM.ts): dom utilities · Helpers for querying and patching Moodle page structure. · `src/_lib/DOM.ts`
- [Moodle AMD](https://github.com/adityaboghara/better-moodle/blob/main/src/_lib/require.js.ts): moodle interop · Integration layer for Moodle RequireJS modules and templates. · `src/_lib/require.js.ts`
- [i18n Core](https://github.com/adityaboghara/better-moodle/blob/main/src/i18n/i18n.ts): localization · Shared translation formatting and language loading. · `src/i18n/i18n.ts`

### Features

Independent Moodle feature modules grouped by subsystem.

- [Courses](https://github.com/adityaboghara/better-moodle/blob/main/src/features/courses/index.ts): feature bundle · Course-page enhancements such as cards, grades, navigation, and role changes. · `src/features/courses/index.ts`
- [General](https://github.com/adityaboghara/better-moodle/blob/main/src/features/general/index.ts): feature bundle · Global visual and navigation tweaks reused across Moodle pages. · `src/features/general/index.ts`
- [Dashboard](https://github.com/adityaboghara/better-moodle/blob/main/src/features/dashboard/index.ts): feature bundle · Dashboard layout and course block/sidebar adjustments. · `src/features/dashboard/index.ts`
- [Messages](https://github.com/adityaboghara/better-moodle/blob/main/src/features/messages/index.ts): feature bundle · Messaging enhancements such as hotkeys and markdown support. · `src/features/messages/index.ts`
- [Weather](https://github.com/adityaboghara/better-moodle/blob/main/src/features/weather/index.tsx): feature bundle · Weather widget backed by multiple third-party providers. · `src/features/weather/index.tsx`
- [Canteen](https://github.com/adityaboghara/better-moodle/blob/main/src/features/speiseplan/index.tsx): feature bundle · Menu and canteen integration for campus food plans. · `src/features/speiseplan/index.tsx`
- [NINA](https://github.com/adityaboghara/better-moodle/blob/main/src/features/nina/index.tsx): feature bundle · Emergency alert integration for campus- or region-level notices. · `src/features/nina/index.tsx`
- [Marquee](https://github.com/adityaboghara/better-moodle/blob/main/src/features/navbarMarquee/index.ts): feature bundle · Top-bar marquee and event/time announcements. · `src/features/navbarMarquee/index.ts`
- [CAU Fixes](https://github.com/adityaboghara/better-moodle/blob/main/src/fixes/cau/loginDivider.tsx): institution fixes · University-specific patches for CAU Kiel. · `src/fixes/cau/loginDivider.tsx`
- [UZL Fixes](https://github.com/adityaboghara/better-moodle/blob/main/src/fixes/uzl/zensus.ts): institution fixes · University-specific patches for Universität zu Lübeck. · `src/fixes/uzl/zensus.ts`

### Build

Custom Vite-based tooling and auxiliary runtime pieces.

- [Tooling](https://github.com/adityaboghara/better-moodle/blob/main/tooling/framework.ts): build pipeline · Custom build and assembly pipeline for userscript packaging. · `tooling/framework.ts`
- [ICS Parser](https://github.com/adityaboghara/better-moodle/blob/main/ics-parser/index.ts): aux runtime · Separate worker-style parser for calendar and recurrence data. · `ics-parser/index.ts`

### External Boundaries

Typed interfaces to Moodle, browser APIs, and third-party data.

- [Require Types](https://github.com/adityaboghara/better-moodle/blob/main/types/require.d.ts): ambient typings · Typed boundary describing Moodle AMD modules, templates, and selectors. · `types/require.d.ts`

## Connections

- Core → Feature Base: registers · Core bootstraps feature lifecycle and registration.
- Core → Global Fixes: applies · Loads broad Moodle patches before feature execution.
- Core → i18n Core: loads · Initializes language packs and shared formatting.
- Core → TempStorage: reads/writes · Uses local storage for preferences and runtime state.
- Core → Settings UI: opens · Wires settings UI into the userscript.
- Core → Courses: enables · Installs course-related feature bundle.
- Core → General: enables · Installs global visual and navigation tweaks.
- Core → Dashboard: enables · Installs dashboard-specific enhancements.
- Core → Messages: enables · Installs message composer and readability features.
- Core → Weather: enables · Installs weather widget features.
- Core → Canteen: enables · Installs canteen/menu integration.
- Core → NINA: enables · Installs emergency alert integration.
- Core → Marquee: enables · Installs marquee/event announcement features.
- Core → CAU Fixes: targets · Includes CAU-specific fixes when configured.
- Core → UZL Fixes: targets · Includes UZL-specific fixes when configured.
- Migrate Storage → TempStorage: migrates · Transforms persisted settings to newer schemas.
- Cleanup Storage → TempStorage: cleans · Removes obsolete persisted data.
- Browser Check → Moodle AMD: detects · Uses Moodle/browser environment assumptions for compatibility warnings.
- Courses → DOM Helpers: patches · Manipulates Moodle page structure and course views.
- Courses → Shared UI: renders · Uses shared UI controls and drawers.
- Messages → DOM Helpers: patches · Extends message page behavior and editing flows.
- Weather → Tooling: fetches · Consumes external weather providers through the feature build.
- Canteen → Tooling: fetches · Consumes campus menu data and parser adapters.
- NINA → Tooling: fetches · Consumes external emergency alert data.
- Tooling → Require Types: validates · Build-time typing boundary for Moodle integrations.
- Tooling → ICS Parser: bundles · Connects the main userscript with the separate parser runtime.
