- Mentingo LMS Core Project
- Course Structure: Courses built from categories, modules and various lesson types
- Lesson Types: Supports text, video, presentation and quiz lessons
- Quiz Engine: Multiple-choice, single-choice, true/false, gap-filling, short/long text answers and image-based questions
- Price Configuration: Flexible setup for free and paid course access
- Progress Tracking: Automatic progress saving and course completion logic
- Daily Streak Tracking: Motivational system for tracking learning consistency
- Statistics & Insights: Detailed data on user engagement and learning results
- Admin Panel: Tools for managing users, courses, content and statistics
- User Roles: Separate experiences for students and administrators
- api: A NestJS backend application working as API
- web: A Vite Remix SPA
- reverse-proxy: For domains and https during development
- email-templates: A package for email templates
- eslint-config: A package for eslint configuration
- typescript-config: A package for typescript configuration
Before you begin, make sure you have:
- Node.js version 20.15.0 (stated in
.tool-versions)- We recommend using asdf for version management
- pnpm package manager
- Caddy v2.8.4 (optional - see Running Without Caddy)
- Docker and Docker Compose
Install project dependencies:
pnpm installConfigure Caddy (first-time setup only):
cd ./apps/reverse-proxy
caddy run
# After running caddy just terminate the process with Ctrl+CImportant
First run has to be run by hand to configure caddy. Later on it will automatically start with the app start script.
Note
Caddy tries to bind to port 443. On Unix/Linux systems, ports below 1024 are privileged, meaning only processes with special permissions (or root) can use them. If you encounter an error, you might have to grant it permission to bind to privileged ports by running:
sudo setcap 'cap_net_bind_service=+ep' $(which caddy)You can run the project without Caddy. Vite has a built-in proxy that automatically routes /api requests to the API server.
-
Set environment variables:
In
apps/web/.env:VITE_APP_URL=
In
apps/api/.env:CORS_ORIGIN=http://localhost:5173 FRONTEND_URL=http://localhost:5173
-
Start the applications:
# Terminal 1: Start API cd apps/api pnpm dev # Terminal 2: Start Web App cd apps/web pnpm dev
-
Access the applications:
- Web App:
http://localhost:5173 - API:
http://localhost:3000/api - Swagger:
http://localhost:3000/api
- Web App:
Note
When running without Caddy, you won't have HTTPS or custom domains. The Vite dev server will automatically proxy /api requests to the API server on port 3000.
Configure environment variables for both applications:
cd apps/api
cp .env.example .envcd apps/web
cp .env.example .envNote
In project root.
- Start the database:
docker compose up -d- Run migrations:
pnpm db:migratePopulate the database with initial data:
pnpm db:seedNote
Make sure your .env variables are set correctly. Otherwise, you might run into errors when running E2E tests.
After running the database seeding AFTER renaming the teacher role to content creator, the following default accounts are available:
| Role | Password | |
|---|---|---|
| Student | student@example.com | password |
| Student | student2@example.com | password |
| Content Creator | contentcreator@example.com | password |
| Content Creator | contentcreator2@example.com | password |
| Admin | admin@example.com | password |
Note
These accounts are created during the seeding process and are intended for development and testing purposes only.
To start all applications in development mode:
pnpm devAfter starting the development environment, you can access:
| Service | URL | Description |
|---|---|---|
| Web App | https://app.lms.localhost | Frontend application |
| API | https://app.lms.localhost/api | Backend API url |
| Swagger | https://api.lms.localhost/api | API documentation |
| Mailhog | https://mailbox.lms.localhost | Email testing interface |
- Format all files with Prettier
pnpm format
- Check if all files are formatted with Prettier
pnpm format:check
- Lint all files in the web app with ESLint
pnpm lint-tsc-web
- Lint all files in the api app with ESLint
pnpm lint-tsc-api
- Fix linting errors in the web app
pnpm lint-tsc-web --fix
- Fix linting errors in the api app
pnpm lint-tsc-api --fix
- Generate new migration:
pnpm db:generate
Important
After generating a migration:
- Change its name to something descriptive that explains what it does
- Make sure to update the migration name in
apps/api/src/storage/migrations/meta/_journal.jsonunder thetagkey
- Run migrations:
pnpm db:migrate
- Generate TypeScript API client based on Swagger specification:
pnpm generate:client
- Build email templates:
cd packages/email-templates pnpm build
Email templates are automatically built when starting the development server. To test emails, check the Mailhog interface at mailbox.lms.localhost.
-
Frontend tests:
-
Unit
pnpm test:web
-
E2E
bash test-e2e.sh
or
chmod +x test-e2e.sh ./test-e2e.sh
-
-
Backend tests:
pnpm test:api # Unit tests pnpm test:api:e2e # E2E tests
lms-core
├── apps
│ ├── api
│ │ ├── src
│ │ └── test
│ ├── reverse-proxy
│ └── web
│ ├── app
│ │ ├── api
│ │ ├── assets
│ │ ├── components
│ │ └── modules
│ └── e2e
└── packages
├── email-templates
├── eslint-config
├── shared
└── typescript-config
We welcome contributions to LMS Core! Please check our Contributing Guide (coming soon) for guidelines about how to proceed.
To ensure consistency and clarity across our development workflow, we follow the naming conventions outlined below.
Each branch name should follow this pattern:
[initials]_[type]_[module]_[ticket]_[short_description]
Components:
initials– First letter of the author's first and last name, in lowercase (e.g.,jdfor John Doe)type– Type of change:feat– New featurefix– Bug fixchore– Maintenance or build-related tasksrefactor– Code refactoring without functional changes
module– Relevant module or system (e.g.lms)ticket– Ticket or issue number (e.g.459)short_description(optional) – Brief description insnake_case
Example:
jd_feat_lms_459_implement_sso
We follow the Conventional Commits specification.
Format:
<prefix>: description of the change
Examples:
feat: implement SSO authentication
fix: resolve token expiration issue
Pull Requests should:
- Use conventional title format:
feat(LMS-459): Implement SSO authentication
fix(LMS-482): Resolve token expiration issue
refactor(LMS-501): Simplify chart rendering logic
- Follow the project's PR template and fill out all required sections
- Provide a brief description of the change and link to the related ticket
- Include screenshots, test results, or instructions if applicable
See Deployment Guide for more details.
This project was generated using Selleo LMS which is licensed under the MIT license.
Ready to scale your eLearning platform? Selleo will help with product-minded dev teams who are here to make it happen.

