Headless LMS

Project structure

How the monorepo is organized and what each workspace is responsible for.

The project is a pnpm monorepo. The core server, adapters and plugins are published as packages and can be installed using npm install @headless-lms/server.

repository
headless-lms/
├─ apps/
│  ├─ api/                   # @headless-lms/api — reference server installation
│  ├─ admin/                 # Next.js admin back-office
│  ├─ student/               # Next.js student portal
│  └─ website/               # public docs and marketing site
├─ packages/
│  ├─ core/                  # @headless-lms/core — the domain: contexts, reporting, types, schemas
│  ├─ server/                # @headless-lms/server — composition root + Fastify HTTP layer
│  ├─ sdk/                   # @headless-lms/sdk — generated typed client
│  ├─ editor/                # @headless-lms/editor — activity editor contract
│  ├─ cli/                   # @headless-lms/cli — headless-lms bin
│  └─ create-headless-lms/   # create-headless-lms — installation scaffolder
├─ plugins/
│  ├─ slack/                 # @headless-lms/plugin-slack
│  └─ content-plate/         # @headless-lms/content-plate editor plugin
├─ adapters/
│  ├─ db/                    # @headless-lms/adapter-db — Drizzle schema, repositories, migrations
│  ├─ auth/                  # @headless-lms/adapter-auth — Better Auth
│  ├─ defaults/              # @headless-lms/adapter-defaults — in-process bus, logging, stubs
│  ├─ email-resend/          # @headless-lms/adapter-email-resend
│  ├─ email-templates/       # @headless-lms/adapter-email-templates
│  ├─ storage-minio/         # @headless-lms/adapter-storage-minio
│  └─ workflow-hatchet/      # @headless-lms/adapter-workflow-hatchet
├─ docs/                     # internal architecture and domain notes
└─ docker/                   # Postgres + MinIO for local dev

Packages

  • @headless-lms/core — the framework-free domain: the bounded contexts, their ports, the type surface (@headless-lms/core/types) and the Zod HTTP schemas (@headless-lms/core/schemas).
  • @headless-lms/server — the Fastify HTTP layer and the composition root that wires core to its adapters. Persistence is Drizzle and Postgres, in @headless-lms/adapter-db.
  • @headless-lms/sdk — the typed client, generated from the OpenAPI spec that the server produces.
  • create-headless-lms — the scaffolder behind npm create headless-lms.

Apps

  • apps/api — an example installation that composes the server with sane defaults. Use it as a reference for your own.
  • apps/admin — the Next.js admin dashboard for courses, students, entitlements, and reporting.
  • apps/student — the Next.js app where students log in and take their courses.

Composing an installation

An installation composes what it wants with sane defaults — picking storage and email adapters, registering plugins, and owning its config. See apps/api for a working example.

On this page