Skip to content

scormflow/scorm-engine

Repository files navigation

ScormFlow — Server

Open-source infrastructure for SCORM, xAPI, and cmi5 — with built-in LRS, webhooks, and AI analytics. Headless, API-first runtime engine. Embed it in a Node app, run it as a Docker container, or pair it with @scormflow/react. Vendor-neutral REST API, end-to-end typed.

License: MIT Node TypeScript


Why ScormFlow

Existing open-source SCORM projects are either runtime libraries (no persistence) or full LMS forks (everything you don't want). ScormFlow is the missing middle: a small, embeddable engine that handles parsing, runtime APIs, tracking, and analytics — and stops there. You compose the LMS on top.

  • Pluggable everywhere — storage (local / S3 / R2 / MinIO), auth (API key / JWT), database (Postgres / SQLite), AI provider (BYO key).
  • Standards-first — SCORM 1.2, SCORM 2004, xAPI, and cmi5 share one normalized event model.
  • Headless — every UI feature in the ecosystem is built on the public REST API. No private endpoints.
  • Zero third-party SCORM libraries — clean-room implementation of the SCORM JS APIs. Any spec-compliant course works.

Quick Start

Docker

git clone https://github.com/scormflow/scorm-engine.git
cd scorm-engine
cp .env.example .env
docker compose -f docker/docker-compose.yml up

The engine is now live on http://localhost:3000. Health check: GET /healthz.

Embed in a Node app

npm install @scormflow/server
import { buildApp, loadEnv } from '@scormflow/server';

const env = loadEnv();
const app = await buildApp({ env });
await app.listen({ port: 3000 });

REST API (excerpt)

Full spec: openapi/openapi.yaml.

POST   /api/v1/courses               Upload + register a SCORM package
POST   /api/v1/courses/validate      Validate a package without registering
GET    /api/v1/courses               List courses for the tenant
GET    /api/v1/courses/:id           Course metadata + SCO tree
DELETE /api/v1/courses/:id           Delete a course

POST   /api/v1/attempts/start        Start a learner attempt
GET    /api/v1/attempts/:id          Attempt state
POST   /api/v1/attempts/:id/finish   Force-terminate an attempt

POST   /api/v1/runtime/:attemptId/initialize    SCORM Initialize
POST   /api/v1/runtime/:attemptId/value         SetValue / GetValue
POST   /api/v1/runtime/:attemptId/commit        Commit
POST   /api/v1/runtime/:attemptId/terminate     Terminate

GET    /api/v1/analytics/courses/:id
GET    /api/v1/analytics/learners/:id
GET    /api/v1/analytics/overview

Auth: Authorization: Bearer <api-key> for tenant calls; short-lived JWT for runtime calls (issued per attempt).


Architecture

src/
├── core/         Runtime engine (CMI model, validators)        [planned]
├── parser/       imsmanifest.xml + ZIP extraction              [done]
├── runtime/      SCORM 1.2 + 2004 API handlers                 [planned]
├── tracking/     Attempt + progress persistence                [planned]
├── storage/      Pluggable storage adapters                    [local done, S3 planned]
├── analytics/    Analytics + reporting                         [planned]
├── http/         Fastify routes + middleware                   [partial]
├── auth/         API keys + JWT                                [api-key done, jwt planned]
├── services/     Course / attempt / runtime services           [course done]
├── db/           Prisma schema + migrations                    [done]
└── server.ts     Entrypoint

Database: PostgreSQL (production) or SQLite (dev). ORM: Prisma. Schema in prisma/schema.prisma.


Configuration

.env (see .env.example for the full list):

Variable Purpose
DATABASE_URL Postgres / SQLite connection string
STORAGE_DRIVER local, s3
STORAGE_LOCAL_DIR Disk path for local driver
JWT_SECRET Signing secret for runtime tokens
API_BASE_URL Public base URL (used in /play/:attemptId links)

Roadmap

Checkboxes reflect the actual state of main. Source of truth for scope: ../scope.md.

Phase 1 — MVP (foundation)

  • Repo init, TypeScript strict mode, Fastify app skeleton
  • Prisma schema (Tenant, ApiKey, Course, Sco, Learner, Attempt, Interaction, Objective, CommitLog)
  • Pluggable StorageAdapter interface + local disk driver
  • SCORM ZIP extraction (yauzl)
  • imsmanifest.xml parser (fast-xml-parser)
  • SCORM 1.2 / 2004 version detection
  • Course ingestion service (upload → extract → parse → persist)
  • Course management routes (upload, list, get, delete)
  • Package validation endpoint (POST /courses/validate)
  • API key auth + tenant scoping (requireApiKey preHandler)
  • OpenAPI 3.1 spec as source of truth
  • Dockerfile + docker-compose (engine + Postgres)
  • S3 / R2 / MinIO storage driver
  • JWT issuance for runtime / player tokens
  • Attempt lifecycle routes (/attempts/start, /:id, /:id/finish)
  • CMI data model + value validation (SCORM 1.2)
  • CMI data model + value validation (SCORM 2004)
  • Runtime API routes (initialize / value / commit / terminate)
  • Resume support (suspend_data, lesson_location persistence)
  • Basic analytics endpoints (course / learner / overview)
  • Standalone iframe player route (GET /play/:attemptId)
  • Drop-in runtime bridge (GET /runtime.js)
  • Multi-tenant rate limiting + isolated storage prefixes
  • End-to-end test: upload → launch → track → resume → complete

Phase 2 — Strong differentiators

  • xAPI 1.0.3 statement endpoint + state / activity / agent profile APIs
  • Built-in LRS (xAPI store, queryable, pluggable backend)
  • cmi5 launch + registration management
  • cmi5 session lifecycle (initialized → completed / passed / failed / terminated / abandoned)
  • Webhook system (signed payloads, retries, delivery log)
  • Offline sync queue + reconciliation
  • Certificate engine (PDF generation on completion)
  • Event bus (BullMQ / Redis streams)
  • Plugin system (plugins: [analyticsPlugin(), certificatePlugin()])

Phase 3 — Category-defining

  • AI analytics layer with BYO provider + key (OpenAI / Anthropic / Gemini / Mistral / Ollama)
  • PII redaction pass for AI prompts
  • Session replay (event timeline, heatmaps, engagement scoring)
  • Git-style course versioning (releases, diffs, rollback)
  • Universal Learning Content Gateway (SCORM / xAPI / cmi5 / H5P / HTML / video / PDF)
  • Compliance dashboards (audit log, attestation, certification expiry)
  • Learning data warehouse export (BigQuery / Snowflake / Redshift / S3 Parquet)

Development

pnpm install                # or npm install
pnpm db:generate            # generate Prisma client
pnpm db:migrate             # run migrations
pnpm dev                    # tsx watch
pnpm test                   # vitest
pnpm openapi:lint           # validate OpenAPI spec
pnpm build                  # tsc → dist/

Requires Node ≥ 20.


Contributing

Issues and PRs welcome. Before opening a PR:

  • Run pnpm typecheck && pnpm test && pnpm openapi:lint.
  • Match the existing style (Biome / ESLint settings in repo).
  • For new endpoints, update openapi/openapi.yaml — it's the contract the client repo depends on.

Security

See SECURITY.md for vulnerability disclosure.

License

MIT — see LICENSE.

Related repos

About

Open-source infrastructure for SCORM, xAPI, and cmi5 — with built-in LRS, webhooks, and AI analytics. Pluggable storage and auth, vendor-neutral REST API, works with any player or our @scorm-engine/client SDK. End-to-end typed.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors