Best Boilerplates for Online Course Platforms in 2026
·StarterPick Team
online-courselmseducationboilerplate2026
Online Course Platforms: Content + Commerce
Building a course platform from scratch means: video delivery, curriculum structure, progress tracking, quizzes, certificates, payment (one-time + subscription), student management, and a good student learning experience.
Most course creators use Teachable, Kajabi, or Thinkific instead of building. But if you're building a platform for others — a white-label LMS or a specialized education product — a custom boilerplate makes sense.
Build vs Platform Decision First
| Monthly Revenue | Recommendation |
|---|---|
| $0-$5k | Teachable Free / Gumroad / Lemon Squeezy |
| $5k-$50k | Kajabi ($149/mo) or Teachable ($39/mo) |
| $50k+ | Custom platform (worth the development investment) |
| White-label LMS | Custom from day one |
Building a custom course platform makes sense for:
- White-label LMS — selling the platform itself to others
- Community-integrated learning — tight integration between courses and community
- B2B training — enterprise SSO, team management, compliance tracking
Quick Comparison
| Starter | Price | Video | Progress | Payments | CMS | Best For |
|---|---|---|---|---|---|---|
| Payload CMS + Next.js | Free | Manual | Manual | Stripe | ✅ | Custom LMS foundation |
| Open edX | Free (complex) | ✅ | ✅ | ✅ | ✅ | Enterprise LMS |
| Moodle | Free | ✅ | ✅ | ✅ | ✅ | Academic LMS |
| Supastarter + custom | $299 | Manual | Manual | Stripe | ❌ | SaaS foundation + courses |
Building a Course Platform on Next.js
The core data model:
// Prisma schema for course platform
model Course {
id String @id @default(cuid())
title String
description String
price Decimal? // null = free
slug String @unique
published Boolean @default(false)
modules Module[]
enrollments Enrollment[]
instructor User @relation(fields: [instructorId], references: [id])
instructorId String
}
model Module {
id String @id @default(cuid())
title String
order Int
lessons Lesson[]
course Course @relation(fields: [courseId], references: [id])
courseId String
}
model Lesson {
id String @id @default(cuid())
title String
videoUrl String? // Mux or Cloudflare Stream URL
content String? // MDX content
order Int
completions LessonCompletion[]
module Module @relation(fields: [moduleId], references: [id])
moduleId String
}
model Enrollment {
id String @id @default(cuid())
student User @relation(fields: [studentId], references: [id])
studentId String
course Course @relation(fields: [courseId], references: [id])
courseId String
createdAt DateTime @default(now())
@@unique([studentId, courseId])
}
Video Delivery
Don't use YouTube or self-hosted video. Use:
- Mux — $0.015/min storage + $0.005/min viewed. Best developer experience.
- Cloudflare Stream — $5/1000 min stored + $1/1000 min viewed. Cheaper at scale.
- Bunny.net — $10/TB storage + $9/TB bandwidth. Lowest cost for high volume.
// Upload video to Mux
import Mux from '@mux/mux-node';
const mux = new Mux();
const upload = await mux.video.uploads.create({
new_asset_settings: { playback_policy: ['signed'] },
cors_origin: 'https://yourdomain.com',
});
// Return upload URL to client for direct browser upload
return { uploadUrl: upload.url, assetId: upload.id };
Compare course platform and SaaS boilerplates on StarterPick.
Check out this boilerplate
View Payload CMS + Next.js on StarterPick →