Back
In print settings: Save as PDF, turn headers and footers off, turn background graphics on.

Contributing to LibreUni

A hands-on project guide and platform feature gallery for authors, contributors, reviewers, and testers.

Official Documentation

July 2026

Contents

Project

  • LibreUni Project Overview

Authoring

  • Authoring Feature Showcase

Workflow

  • Contribution Workflow

Quality

  • Testing and Quality Signals

Project

Section Detail

LibreUni Project Overview

LibreUni Project Overview

LibreUni is a free learning platform built around plain content, static rendering, and interactive components. Lessons are written as MDX, courses are described with small JSON files, and the app turns that material into searchable course pages, lesson pages, exports, exercises, diagrams, and code labs.

The project is intentionally contributor-friendly. A useful change can be a new lesson, a better explanation, a fixed diagram, a more focused quiz, a clearer code sample, or an accessibility improvement.

Repository Map

Code
skinparam backgroundColor transparent
skinparam componentStyle rectangle

package "LibreUni" {
folder "apps/main" {
  [Astro pages] as pages
  [MDX lessons] as lessons
  [Course JSON] as courses
  [Interactive components] as components
}

folder "tests" {
  [Smoke tests] as smoke
  [Accessibility tests] as accessibility
  [UX checks] as ux
}

folder "docs" {
  [Authoring rules] as rules
  [PlantUML notes] as puml
}
}

courses --> pages : course cards
lessons --> pages : lesson routes
components --> lessons : embedded labs
tests --> pages : verify rendered app
docs --> lessons : author guidance
LibreUniapps/maintestsdocsAstro pagesMDX lessonsCourse JSONInteractive componentsSmoke testsAccessibility testsUX checksAuthoring rulesPlantUML notescourse cardslesson routesembedded labsverify rendered appauthor guidance

Click the diagram to open the overlay. Large diagrams should keep their proportions, scale down when needed, and expand cleanly on demand.

What Contributors Usually Touch

AreaCommon filesGood contribution shape
Course metadataapps/main/src/content/courses/*.jsonClear title, description, icon, color, image
Lesson contentapps/main/src/content/lessons/**.mdxFocused lesson with examples, checks, and references
Interactive widgetsapps/main/src/components/*Reusable feature with stable props
Build and teststests/**, tools/**Verifies behavior without slowing normal authorship
Documentationdocs/**, README.mdHelps the next contributor make fewer guesses

Contribution Mindset

A good LibreUni contribution is small enough to review, rich enough to teach, and boring enough to maintain. Prefer one clear idea per lesson section. Use visual and interactive elements when they make the concept easier to understand, not as decoration.

Choosing a First Change

A new contributor notices that a lesson explains state machines only in prose. They can either rewrite the entire UML course, add one focused diagram and quiz to the state-machine lesson, or start by changing the homepage layout.

Which first contribution is easiest to review and most aligned with the project?

Quick Check

What is the main authoring format for LibreUni lessons?

Authoring

Section Detail

Authoring Feature Showcase

Authoring Feature Showcase

This lesson is deliberately dense: it exists so contributors and testers can see the platform surface area in one place. It also works as a pattern catalog for new lessons.

Markdown and Math

Authors can write normal Markdown, tables, code fences, inline math such as f(x)=x2+1f(x)=x^2+1, and display math:

E=ρε001x2dx=13\nabla \cdot \vec{E} = \frac{\rho}{\varepsilon_0} \qquad \int_0^1 x^2\,dx = \frac{1}{3}
type LessonFeature = "markdown" | "math" | "diagram" | "code" | "assessment";

const usefulFeature = (feature: LessonFeature) =>
  feature === "diagram" ? "show structure" : "support understanding";

PlantUML Sequence Diagram

Code
skinparam backgroundColor transparent
actor Contributor
participant "MDX Lesson" as MDX
participant "Astro Build" as Astro
participant "Static Site" as Site

Contributor -> MDX: edit content
MDX -> Astro: import components
Astro -> Site: render pages
Site --> Contributor: preview and test
ContributorMDX LessonAstro BuildStatic SiteContributorMDX LessonAstro BuildStatic SiteContributorMDX LessonAstro BuildStatic Siteedit contentimport componentsrender pagespreview and test

PlantUML Activity Diagram

Code
skinparam backgroundColor transparent
start
:Pick one learning goal;
if (Does a visual help?) then (yes)
:Add PlantUML, TikZ, or Python visual;
else (no)
:Keep the prose lean;
endif
:Add one check for understanding;
:Run the build;
stop
Pick one learning goalDoes a visual help?yesnoAdd PlantUML, TikZ, or PythonvisualKeep the prose leanAdd one check for understandingRun the build

TikZ Diagram

TikZ is useful for precise mathematical and conceptual drawings. This one is rendered at build time and participates in the same click-to-open overlay behavior as PlantUML.

Code
\draw[->, thick] (-0.3,0) -- (4.3,0) node[right] {$x$};
\draw[->, thick] (0,-0.3) -- (0,3.2) node[above] {$y$};
\draw[domain=0.25:4, smooth, variable=\x, blue, very thick] plot ({\x},{0.35*\x*\x});
\draw[dashed] (2,0) -- (2,1.4) -- (0,1.4);
\filldraw[blue] (2,1.4) circle (2pt);
\node[above right] at (2,1.4) {$f(x)=0.35x^2$};
\node[below] at (2,0) {$a$};
\node[left] at (0,1.4) {$f(a)$};

TikZ Rendering Error

The TikZ generation failed during build.

Source Definition
\draw[->, thick] (-0.3,0) -- (4.3,0) node[right] {$x$};
\draw[->, thick] (0,-0.3) -- (0,3.2) node[above] {$y$};
\draw[domain=0.25:4, smooth, variable=\x, blue, very thick] plot ({\x},{0.35*\x*\x});
\draw[dashed] (2,0) -- (2,1.4) -- (0,1.4);
\filldraw[blue] (2,1.4) circle (2pt);
\node[above right] at (2,1.4) {$f(x)=0.35x^2$};
\node[below] at (2,0) {$a$};
\node[left] at (0,1.4) {$f(a)$};

Build-Time Python Diagram

Python diagrams are rendered during the Astro build, cached, and displayed as normal lesson diagrams. This is the standard choice when an author wants Python to generate a stable visual explanation rather than an interactive lab.

Code
import os
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 240)
y = np.sin(x)
z = np.cos(x)

plt.figure(figsize=(8, 4.5))
plt.plot(x, y, label="sin(x)", linewidth=2)
plt.plot(x, z, label="cos(x)", linewidth=2)
plt.fill_between(x, y, z, where=y > z, alpha=0.18)
plt.title("Build-Time Python Diagram")
plt.xlabel("x")
plt.ylabel("value")
plt.legend()
plt.grid(alpha=0.25)
plt.savefig(os.environ["LIBREUNI_OUTPUT"], format="svg", bbox_inches="tight")
2026-07-12T18:15:54.834261 image/svg+xml Matplotlib v3.6.3, https://matplotlib.org/
Build-time Matplotlib SVG

Python SVG Diagram

Python can also generate SVG directly. This is useful for small custom diagrams where using a full plotting library would be heavier than the diagram itself.

Code
nodes = [
  ("Idea", 70, 75, "#2563eb"),
  ("Draft", 220, 75, "#7c3aed"),
  ("Review", 370, 75, "#059669"),
  ("Publish", 520, 75, "#f59e0b"),
]

parts = ['<svg xmlns="http://www.w3.org/2000/svg" width="620" height="170" viewBox="0 0 620 170">']
parts.append('<rect width="620" height="170" rx="18" fill="#f8fafc"/>')
for label, x, y, color in nodes:
  parts.append(f'<circle cx="{x}" cy="{y}" r="34" fill="{color}" opacity="0.92"/>')
  parts.append(f'<text x="{x}" y="{y + 62}" text-anchor="middle" font-family="sans-serif" font-size="14" font-weight="700" fill="#0f172a">{label}</text>')
parts.append('<path d="M104 75 H186 M254 75 H336 M404 75 H486" stroke="#0f172a" stroke-width="5" stroke-linecap="round"/>')
parts.append('</svg>')

with open(__import__("os").environ["LIBREUNI_OUTPUT"], "w", encoding="utf-8") as file:
  file.write("".join(parts))
IdeaDraftReviewPublish
Build-time Python SVG

Runtime Code Lab

The code runner is still useful when learners should experiment with code directly. It is not the standard way to publish stable diagrams, but it remains useful for exploration.

javascript
1const features = ["content", "diagram", "quiz", "preview"];
2console.log(features.map((feature, index) => `${index + 1}. ${feature}`).join("\n"));

Fill-In Exercise

Complete an MDX Import

import  from '../../../components/PlantUML.astro';

< code={\`
Alice -> Bob: hello
\`} />

Which tool is the best fit for a precise mathematical drawing that should render during the static build?

Workflow

Section Detail

Contribution Workflow

Contribution Workflow

The simplest contribution loop is: choose a narrow goal, edit locally, run the build, inspect the rendered page, and open a pull request with a clear summary. The loop is intentionally ordinary because ordinary workflows are easier to repeat.

Pull Request Flow

Code
skinparam backgroundColor transparent
start
:Create a branch;
:Edit content or code;
:Run local checks;
if (Checks pass?) then (yes)
:Open pull request;
:Respond to review;
if (Approved?) then (yes)
  :Merge;
else (changes requested)
  :Patch and rerun checks;
endif
else (no)
:Read the failing output;
:Fix the smallest cause;
endif
stop
Create a branchEdit content or codeRun local checksChecks pass?yesnoOpen pull requestRespond to reviewApproved?yeschanges requestedMergePatch and rerun checksRead the failing outputFix the smallest cause

Review Conversation

Code
skinparam backgroundColor transparent
actor Author
participant "Pull Request" as PR
participant Reviewer
participant "CI Checks" as CI

Author -> PR: Push focused change
PR -> CI: Run build and tests
CI --> PR: Pass/fail signal
Reviewer -> PR: Ask about scope or clarity
Author -> PR: Explain, patch, or split
Reviewer --> Author: Approve when risk is understood
AuthorPull RequestReviewerCI ChecksAuthorPull RequestReviewerCI ChecksAuthorPull RequestReviewerCI ChecksPush focused changeRun build and testsPass/fail signalAsk about scope or clarityExplain, patch, or splitApprove when risk is understood

Useful Local Commands

The command runner can show examples for shells and compiled languages even when they are not executed in the browser. That makes it useful for tutorials about workflows.

bash
1npm install
2npm run build --workspace @libreuni/main
3npm run dev --workspace @libreuni/main -- --host 127.0.0.1 --port 4321

Commit Shape

A small commit message should say what changed and why it matters. It should have the first word in square brackets and indicate the type of change, such as [Add], [Fix], [Update], or [Refactor].

[Add] LibreUni contribution showcase course

Introduces a project-oriented course that demonstrates MDX authoring,
diagrams, code labs, quizzes, case studies, and local contribution flow.
Pull Request Scope

A contributor has three ideas: add a typo fix, add a new lesson, and redesign the course cards. They are unrelated and each has different review risk.

What should they do first?

Why run the local build before asking for review?

Quality

Section Detail

Testing and Quality Signals

Testing and Quality Signals

LibreUni quality is not one test. It is a chain of signals: content reads cleanly, MDX compiles, diagrams render, interactive widgets hydrate, the layout works on mobile and desktop, and the lesson has a clear learning purpose.

Quality Pipeline

Code
skinparam backgroundColor transparent
rectangle "Author edits" as Edit
rectangle "MDX compile" as Compile
rectangle "Diagram render" as Diagrams
rectangle "Static build" as Build
rectangle "Browser preview" as Preview
rectangle "Review" as Review

Edit --> Compile
Compile --> Diagrams
Diagrams --> Build
Build --> Preview
Preview --> Review
Author editsMDX compileDiagram renderStatic buildBrowser previewReview

Visual Sanity Checks

For diagrams, the key quality question is simple: can a reader understand the structure without fighting the layout? The overlay exists so large diagrams can be inspected without squeezing text into unreadable shapes.

Code
\foreach \x/\label in {0/Content,2/Build,4/Preview,6/Review} {
\draw[rounded corners=4pt, fill=blue!8, draw=blue!60, thick] (\x,0) rectangle +(1.35,0.7);
\node at (\x + 0.675,0.35) {\small \label};
}
\draw[->, thick] (1.35,0.35) -- (2,0.35);
\draw[->, thick] (3.35,0.35) -- (4,0.35);
\draw[->, thick] (5.35,0.35) -- (6,0.35);
\draw[rounded corners=6pt, dashed, draw=green!60!black, thick] (-0.25,-0.25) rectangle (7.6,0.95);
\node[below] at (3.65,-0.25) {\small Every step should produce a useful signal};

TikZ Rendering Error

The TikZ generation failed during build.

Source Definition
\foreach \x/\label in {0/Content,2/Build,4/Preview,6/Review} {
\draw[rounded corners=4pt, fill=blue!8, draw=blue!60, thick] (\x,0) rectangle +(1.35,0.7);
\node at (\x + 0.675,0.35) {\small \label};
}
\draw[->, thick] (1.35,0.35) -- (2,0.35);
\draw[->, thick] (3.35,0.35) -- (4,0.35);
\draw[->, thick] (5.35,0.35) -- (6,0.35);
\draw[rounded corners=6pt, dashed, draw=green!60!black, thick] (-0.25,-0.25) rectangle (7.6,0.95);
\node[below] at (3.65,-0.25) {\small Every step should produce a useful signal};

Browser Logic Example

The code runner can execute JavaScript snippets too. Use this for small algorithmic demonstrations where Python would be unnecessary.

javascript
1const checks = ["build", "preview", "review"];
2const status = Object.fromEntries(checks.map((name) => [name, "ready"]));
3 
4console.log(JSON.stringify(status, null, 2));
5console.log("All checks named:", Object.keys(status).join(" -> "));

Python Data Sketch

This example visualizes a fictional quality dashboard. It is intentionally small, but it exercises the same runtime used by scientific and math lessons.

python
1import matplotlib.pyplot as plt
2 
3labels = ["MDX", "Diagrams", "Hydration", "Mobile", "Review"]
4scores = [98, 95, 92, 90, 96]
5 
6plt.figure(figsize=(6, 3.2))
7bars = plt.bar(labels, scores, color=["#2563eb", "#7c3aed", "#059669", "#f59e0b", "#0f172a"])
8plt.ylim(80, 100)
9plt.ylabel("confidence")
10plt.title("Example Quality Signals")
11for bar, score in zip(bars, scores):
12 plt.text(bar.get_x() + bar.get_width() / 2, score + 0.5, str(score), ha="center")
13print("Quality signal chart rendered.")
14 

Review Heuristics

Use this checklist when reviewing a new lesson:

  1. The title and description match the actual content.
  2. The lesson teaches one coherent idea.
  3. Diagrams are legible in the page and in the overlay.
  4. Interactive components have a reason to be there.
  5. Code samples are short enough to inspect.
  6. The page builds without generating new errors.
Quality Triage

A lesson builds successfully, but one diagram is too dense, the quiz checks trivia instead of the learning goal, and a code sample prints twenty lines of unformatted output.

Which review response is most useful?

What is the best reason to keep this course in the project?