Like many of you in this thread, I’ve been looking for a lightweight way to use Discourse natively as an LMS. I find dedicated LMS platforms too bloated, but Discourse’s default “notification decay” (where older topics stop showing as “unread” for new users) makes tracking course progress difficult.
To scratch my own itch, I built a simple solution using a combination of category settings, a tiny backend plugin, and a theme component.
Here is how I set it up, and the open-source code you can use to replicate it!
The Basic Concept: Discourse as an LMS
To make this work, I use standard Discourse features combined with the official Discourse Doc Categories plugin:
- Course = Category: Each course gets its own category.
- Lesson = Topic: Each lesson is a topic within that category.
- Permissions: Members can reply to lessons (to ask questions), but only staff can create new topics.
- Ordering: Lesson order is fixed by creation date. (Tip: This requires a bit of forward-thinking when posting lessons, or you can use the Rails console to quickly backdate topic creation times to force the correct sorting).
- Syllabus: I use the Discourse Doc Categories plugin to designate an “Index Topic.” This index topic acts as the course syllabus/tracker and renders a beautiful outline on the sidebar when users enter the course.
The Missing Piece: True Progress Tracking
The problem with the setup above is that when a new student joins, the older lesson topics don’t show up as “unread,” so they have no way to visually track their progress.
To solve this, I built a backend plugin that directly queries the TopicUser database table for true historical read status, and a frontend Theme Component that transforms the standard Discourse sidebar into a real-time LMS progress tracker.
1. Main Sidebar Progress Badges
The theme component replaces standard blue notification dots with [ read / total ] progress indicators for your course categories.
2. Lesson Completion Checkmarks
When a user clicks into a course, the Docs plugin renders the syllabus. My theme component injects success checkmarks (fa-check) next to the specific lessons the user has finished reading.
3. Course Completion
Once a user reads every topic in the category, the sidebar progress badge automatically transforms into a satisfying completion tick!
How to Install it
Because this requires bypassing the standard Discourse notification cache, you must install both the backend plugin and the frontend theme component.
Step 1: Install the Prerequisite
Ensure you have the official Discourse Doc Categories plugin installed and active. My plugin specifically only targets categories that have an Index Topic configured.
Step 2: Install the Backend API Plugin
Add this to your app.yml below docker_manager and rebuild your container. This provides the lightning-fast API endpoint for read statuses.
Repository Link: https://github.com/zsviczian/discourse-course-progress**
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
- git clone https://github.com/zsviczian/discourse-course-progress.git
Step 3: Install the UI Theme Component
Install this directly via your web browser in Admin > Customize > Themes > Install > From a Git Repository.
Repository Link: https://github.com/zsviczian/discourse-course-progress-theme
I hope this helps others who are trying to build community-driven courses without the bloat of a separate LMS platform! Let me know if you end up using it.



