Open-source project
codelitdev/courselit avatar
codelitdev/courselit

CourseLit: a self-hosted LMS and website builder where the media backend is a separate paid service

Create/Sell courses and digital downloads and publish blogs on your own branded website. An open source alternative to Teachable, Thinkific, Podia and the likes.

1,263 stars257 forksTypeScriptAGPL-3.0

At a glance

What is it?
CourseLit bundles course authoring, a website builder, Stripe payments and student management into one TypeScript monorepo under AGPL-3.0. The catch is that file storage points at MediaLit by default, and the README is candid that analytics are still thin.
Who is it for?
Adopt CourseLit if you want courses, downloads and a blog on one domain you control, and you accept either a MediaLit account or a self-rolled MediaLit instance for file storage. Do not adopt it if you need deep analytics or a fully offline media stack, since the README itself calls analytics very limited and the default upload path leaves your infrastructure.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem CourseLit targets: a paid course platform versus a site you own

Hosted course platforms rent you a storefront on their domain and meter your audience through their pricing tiers. CourseLit's answer is to give you the same primitives (course authoring, student management, payment processing via Stripe, a website builder, custom sales pages) as software you run yourself, so the storefront, the blog and the checkout all sit on a domain you control. The README frames it as a batteries included LMS and an open source alternative to Teachable, Thinkific, Podia, Teachery and LearnDash. The intended user is a solo teacher or small team that already knows how to deploy a Node application and would rather pay for hosting and a media backend than a percentage of course revenue. The repository also lists a cloud hosted option at courselit.app with a 14 day trial and no credit card, so the project is not strictly self-hosting only. That dual model matters for evaluation: the open source code is the same product, but the hosted path removes the deployment work you are otherwise signing up for.

Monorepo layout: pnpm workspaces, apps/web, and where the pieces live

The repository is organised as a monorepo managed with pnpm workspaces, with the deployable application under apps/web. Database migrations live in apps/web/.migrations, and the README states they are named like DD-MM-YY_HH-MM-<migration-purpose>.js specifically so they sort chronologically. That naming convention tells you something about the maintenance model: migrations are not run by a framework command, they are standalone scripts you execute yourself. The README points to deployment/docker/docker-compose.yml as the reference for available environment variables, which means the compose file, not a config schema, is the authoritative list. A widgets document is referenced for extending the application with your own functionality, so the extension surface is widget-based rather than plugin-registry-based. There is also a changeset workflow for publishing packages to NPM, invoked with pnpm exec changeset, which indicates the project treats parts of the codebase as publishable libraries rather than a single closed application.

Getting it running: pnpm install, pnpm build, pnpm dev

The development path in the README is short. Clone the repository, cd into it, replace the values in the .env file inside apps/web with your environment's configuration, then from the root run pnpm install, pnpm build and pnpm dev. The README notes you can then dive into the code base. For deployment there is a Vercel button that clones the repository and asks for DB_CONNECTION_STRING, AUTH_SECRET, SUPER_ADMIN_EMAIL, EMAIL_USER, EMAIL_PASS, EMAIL_HOST and EMAIL_FROM, with the project root set to apps/web and a build command that runs yarn build from the parent directory with NODE_OPTIONS=--openssl-legacy-provider. That build flag is worth noting: it implies a dependency chain that still needs the legacy OpenSSL provider, which is the kind of detail that bites on newer Node versions. The presence of SUPER_ADMIN_EMAIL as a required variable suggests the first privileged account is created from configuration rather than through a setup wizard. The README does not spell out that bootstrap sequence, so treat it as something to confirm against the self-hosting guide before you plan a deployment.

Migrations are scripts you run by hand, not a command you invoke

This is the most operationally distinctive part of CourseLit. To apply a migration, the README tells you to create a blank Node project with mkdir migration, cd migration and npm init -y, install dependencies (usually npm i mongoose nanoid, with the migration's first lines indicating what is actually needed), copy the migration script into that folder, then run it with DB_CONNECTION_STRING=mongodb://<mongodb-url> node migration-script.js. The README's own wording is that migrations are complete scripts and you need some development chops, not much. There is no migrate up command and no recorded migration state that the documentation describes. In practice that means you are responsible for knowing which scripts have already run against your database, and for running them against the right connection string. For a single administrator this is manageable. For a team with staging and production databases, it is a process you have to invent yourself, and the failure mode is a script applied twice or applied to the wrong database. The chronological filename convention helps you order them but does not track them.

MediaLit: the storage backend that is not in the box

CourseLit uses MediaLit as its backend for managing media assets. The README is direct about the terms: it is a paid service and you need an account on it to store your files in the cloud. If you do not want the cloud hosted version you can roll your own instance and point CourseLit at it with MEDIALIT_SERVER=medialit_server_location in the .env file. This is the single largest architectural decision a self-hoster faces, and it is easy to miss when skimming the feature list. Course content is largely media: video lessons, downloadable files, images for sales pages. Choosing CourseLit means your upload path is a second service with its own deployment, its own storage costs and its own availability profile. Self-rolling MediaLit removes the vendor dependency but adds an operational one. The README does not describe MediaLit's own storage backends or requirements, so how much work rolling your own actually is cannot be determined from this material alone. That is the first thing to investigate before committing.

Where CourseLit is the wrong tool

The README describes analytics as very limited as of now, in its own parenthetical. If your decision to change platforms depends on cohort retention curves, funnel attribution or per-lesson drop-off, CourseLit does not claim to provide them, and you would be bolting on separate tooling. The absence of a managed migration runner is a second boundary: teams that expect schema changes to be applied automatically on deploy will find the copy-and-run script workflow a step backwards. Third, the MediaLit dependency means CourseLit is not a single-container deploy in the way some self-hosted CMS projects are; you are running at least the application, MongoDB, and a media service. Finally, the project is AGPL-3.0. For someone running a course business on their own domain, that is largely unremarkable. For anyone planning to take the code, modify it, and offer it as a hosted service, the network copyleft terms are the thing to read carefully with a lawyer rather than skim. Nothing here is legal advice, and the licence text is the authority.

Open edX and Moodle take a different approach to the same problem

The topics list on the repository includes open-edx, and the contrast is instructive. Open edX and Moodle are learning management systems first: the unit of organisation is the course and the institution, with cohorts, enrolments, grading, roles and reporting as core concerns, and the public website as something you attach or build separately. CourseLit inverts that. Its unit is the creator's own branded site, with courses and digital downloads as things you sell from it, and the README's feature list leads with course authoring, student management, Stripe payments, website builder, custom sales pages and analytics. If your requirement is a departmental teaching platform with assessment workflows, CourseLit's feature list does not describe that. If your requirement is a storefront with a blog that also happens to host lessons, the heavier LMS route means running an institution-grade system to sell a handful of courses, and building the marketing site alongside it. The difference is not quality, it is which object sits at the centre of the data model.

Maintenance cost, version cadence and what to check before you adopt

The release history shows steady, incremental work: v0.73.15 added course previews, v0.74.0 added course discussions, v0.74.2 added reactions for community posts and comments. These are feature-sized releases on a 0.x version line, not a stabilised 1.0, and the last push recorded is September 2026. A 0.x cadence with frequent small releases is normal for a young project and means upgrade work is continuous rather than occasional. Because migrations are manual scripts, each upgrade that touches the schema adds a step to your own runbook. Add the pnpm workspace build, the changeset publishing flow, and the MediaLit service to the list of things that can break independently. Before adopting, verify three things against the documentation rather than assuming: whether the self-hosting guide covers the SUPER_ADMIN_EMAIL bootstrap, what rolling your own MediaLit instance actually requires, and whether the docker-compose.yml in deployment/docker lists environment variables beyond the seven the Vercel button asks for. Those three answers determine whether this is a weekend deployment or a project.

Editorial conclusion

Adopt CourseLit if you want courses, downloads and a blog on one domain you control, and you accept either a MediaLit account or a self-rolled MediaLit instance for file storage. Do not adopt it if you need deep analytics or a fully offline media stack, since the README itself calls analytics very limited and the default upload path leaves your infrastructure. Before committing, verify that your .env in apps/web holds DB_CONNECTION_STRING, AUTH_SECRET, SUPER_ADMIN_EMAIL and the EMAIL_* keys, and decide whether MEDIALIT_SERVER points at your own instance or at the paid cloud service.

Official sources

  1. codelitdev/courselit on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes