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 publised as packages and can be
installed using npm install @headless-lms/server.
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/
│ ├─ server/ # @headless-lms/server — backend library
│ ├─ api-contract/ # @headless-lms/api-contract — Zod HTTP schemas
│ ├─ sdk/ # @headless-lms/sdk — generated typed client
│ ├─ types/ # @headless-lms/types — published type surface
│ ├─ utils/ # @headless-lms/utils — integration runtime helpers
│ ├─ editor-contract/ # @headless-lms/editor-contract — editor shared types
│ ├─ 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/
│ ├─ email-resend/ # @headless-lms/adapter-email-resend
│ ├─ email-templates/ # @headless-lms/adapter-email-templates
│ └─ storage-minio/ # @headless-lms/adapter-storage-minio
├─ docs/ # internal architecture and domain notes
└─ docker/ # Postgres + MinIO for local devPackages
@headless-lms/server— a framework-free domain core behind a Fastify HTTP layer, persisted with Drizzle and Postgres. The backend ships as this library.@headless-lms/sdk— the typed client, generated from the OpenAPI spec that the server produces.create-headless-lms— the scaffolder behindnpm 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.