Multi-course patterns¶
How agencies and platform teams organize several LessonKit courses.
One repo per course (recommended default)¶
customer-a-phishing/ ← npx @lessonkit/cli init
customer-a-onboarding/
shared-brand-theme/ ← optional npm package
Pros: Simple CI, isolated semver pins, clear LMS ownership.
Cons: Duplicate boilerplate unless you extract shared UI.
Use npx @lessonkit/cli init for each course. Pin @lessonkit/* to the same semver across repos when you want aligned behavior.
Monorepo of courses¶
courses/
├── phishing-101/
├── onboarding/
└── compliance-q4/
package.json ← npm workspaces
Add each course as an npm workspace. Root scripts:
{
"scripts": {
"build:all": "npm run build --workspaces --if-present",
"package:all": "npm run package:scorm12 --workspaces --if-present"
}
}
Pros: Shared components, one lockfile, matrix CI.
Cons: Coupled releases; ID collisions if courseId values overlap in telemetry.
Activity IRI strategy¶
Each course needs a unique xAPI activity IRI in lessonkit.json:
"tracking": {
"xapi": {
"activityIri": "https://learn.example.com/courses/phishing-101"
}
}
Pattern |
Example |
|---|---|
Per tenant |
|
Per LMS |
|
Global catalog |
|
Keep IRIs stable across semver bumps unless you intentionally fork reporting.
CI matrix example (GitHub Actions)¶
strategy:
matrix:
course: [phishing-101, onboarding, compliance-q4]
steps:
- run: npm ci
- run: npm run build -w ${{ matrix.course }}
- run: npx lessonkit package --target scorm12 --cwd courses/${{ matrix.course }}