First time building an LMS: SCORM

In recent years, learning has taken a leap from traditional classrooms to virtual platforms, and the learning management system (LMS) is at the heart of this transformation. If you’re unfamiliar with what an LMS is or how it’s revolutionising the education and training industries, this article is for you. We’ll dive deep into the core components of an LMS, including content creation and delivery, tracking, and the critical role of SCORM in promoting standardisation and interoperability.

What is an LMS?

If you don’t know
An LMS is software designed for the efficient creation, delivery, management, and tracking of educational and training materials. Popular LMS options include well-known platforms like Moodle, Google Classroom, and Blackboard Learn. Even if you have not used them, you have probably heard of at least one of them. A rise in their popularity in recent years can be closely linked to the increased demand for fully remote learning experiences LMS platforms play pivotal roles in these two key areas and are a vital part of the LMS we are building:
Content creation and delivery
A significant aspect of using an LMS is content creation. Educational content typically encompasses various formats such as images, videos, text, and other interactive digital assets. The LMS you choose can determine how you create and configure learning materials using these different types of assets, offering various features and options for content development.
As much as you need to create and deliver the content, you also need to be able to track the learner’s interactions with the content. Things such as completion, progress, answers, time spent, and other similar metrics would be interesting to the learner and vital to the administrator to track the learners’ performance. These were some of the things we knew going into this. However, here is where things take an intriguing turn:

Unveiling SCORM – The key to standardisation and interoperability

Imagine a scenario where you’re tasked with solving these two questions: 
  1. What is the best way to create a meaningful and effective learning experience for the learners? 
  2. How do we enable administrators to create an effective and meaningful learning experience? 

Your first instinct, as a developer, might be to design a course-building interface. However, there’s a fascinating twist to this story. During the concept design phase of a project, we discovered that the client had (what we thought to be) a unique workflow. They were creating the learning content in a different platform, known as an authoring tool, distinct from the LMS they used to deliver the content. They used the words “export as SCORM” while describing this process. A quick Google search led us to a world where “SCORM” and “LMS” were inextricably linked.  What we stumbled upon is one of the current LMS standards.

So then, what exactly is SCORM?

Sharable Content Object Reference Model is a technical specification for eLearning platforms and is primarily used to standardise and allow interoperability. Think of it this way: just like you can buy any DVD player and expect it to play a DVD, SCORM ensures that you can create content with any authoring tool, export it as a SCORM file, and import it into any LMS that supports the SCORM standard. 

SCORM stands out as one of the most widely used and supported content standards for LMS platforms. Just to give you an idea, here is a list of 462 SCORM 1.2 compliant LMSs. This being said, it is not the latest and greatest. xAPI, or TinCan API, is the latest and offers tracking in multiple contexts, not just within an LMS. cmi5 is a specific profile of xAPI and is described by them as “cmi5 = xAPI + LMS”. 

A SCORM file at a quick glance

It is a ZIP file. Inside the ZIP file is a collection of HTML files, Javascript files, assets such as images, videos, PDFs, etc, and an XML file that is used by the LMS to understand the configuration of the SCORM file.

Under the hood

The manifest file (imsmanifest.xml) is an important file, as it describes the structure, configuration and entry point of the content. The LMS needs to interpret the manifest file and load the entry point as specified by the LMS. The content folder contains the actual content. Finally, an assets folder containing various other assets to be used in the learning content.


You might be looking at the structure thinking, well, it is pretty straightforward. The truth behind it is that it is. The SCORM api is the one remaining piece that is crucial to the SCORM standard. Its purpose is to enable and standardise the communication between the content and the LMS hosting it. The type of communication here relates to the learner’s interaction with the SCORM content – progress, scores, completion status, and other relevant data. 

The SCORM API consists of the following methods:

  • Initialise – used to initiate a connection between the content package and the LMS. 
  • Terminate – this is called when the content is exiting or closing.
  • GetValue and SetValue – used to retrieve and update user data from the LMS
  • Commit – this method tells the LMS to save any changes made by the content package
  • Finish – used to indicate that the content has completed its tasks and can be safely terminated.

How we used SCORM

We established a good understanding of SCORM and realised the best approach would be to adhere to the current LMS standards and enable our LMS to be ‘SCORM compliant’. What this means is the client can continue to follow the same content creation process on the same platform using the same expertise.

The technical details

The LMS needs to be able to store SCORM zip files securely on the backend, it needs to be able to download the SCORM files to the client application and present them, and it then needs to implement the SCORM API so that the SCORM content can correctly communicate with the LMS. 

Fetching the content

In our case, the data is stored on an S3 bucket on AWS since our backend is built on AWS services. The zip file is downloaded, unzipped, and stored on the local device.

Presenting the content

Presenting the content is as simple as loading the SCORM entry point in an iframe. Determining which file is the entry point is specified in the imsmanifest.xml file. As seen below (an excerpt from a manifest file), I would need to load the scormdriver/indexAPI.html file in the iframe.

					<?xml version="1.0" ?>
<manifest identifier="umgA90Asn2C5GFzi4-NTkmRqazi1IqDatzBPZbV9" version="1"
  xsi:schemaLocation=" imscp_rootv1p1p2.xsd adlcp_rootv1p2.xsd">

    <schema>ADL SCORM</schema>
  <organizations default="articulate_rise">
    <organization identifier="articulate_rise">
      <title>Employee Health and Wellness (Sample Course)</title>
      <item identifier="i1" identifierref="r1" isvisible="true">
        <title>Employee Health and Wellness (Sample Course)</title>
    <resource identifier="r1" type="webcontent" adlcp:scormtype="sco" href="scormdriver/indexAPI.html">
      <!-- SCORMDRIVER STUFF -->
      <file href="scormdriver/indexAPI.html" />
      <file href="scormdriver/preloadIntegrity.js" />


Implementing the SCORM API requires you to create a class that implements the methods specified earlier in the article. That class needs to be assigned to an API field on the window so it can be accessed by the SCORM content when loaded in the iframe. Below is an example of this implementation. The process I followed was to console.log all the events, then when interacting with the SCORM content, I could see what data was being sent in each event, which helped me build the functionality to save and use the data correctly.

					export class ScormAPI {

  LMSInitialize(data: any): boolean | string {
    // TODO initialise any other data you need to
    return LMS.returnBooleanStrings ? "true" : true;
  LMSTerminate(data: any): boolean | string {
    // TODO save any data that has not been saved
    return LMS.returnBooleanStrings ? "true" : true;
  LMSGetValue(path: string): string {
    // TODO fetch a value that has previously been persisted to the backend
    return "";
  LMSSetValue(path: string, value: string): boolean | string {
    switch (path) {
      case ScormDataPoints.SESSION_TIME:
        // Save the session time
      case ScormDataPoints.LESSION_LOCATION:
        // Save the lesson that is currently in view
      case ScormDataPoints.SUSPEND_DATA:
        // Save the lesson that is currently in view
      case ScormDataPoints.COMPLETION_STATUS:
        // Record the lesson completion status: completed/not_completed
      case ScormDataPoints.LESSON_STATUS:
        // Record the lesson status: pass/fail
      case ScormDataPoints.INTERACTIONS_ID:
        // Record the interaction ID
      case ScormDataPoints.INTERACTIONS_RESPONSE:
        // Record the interaction response
    return LMS.returnBooleanStrings ? "true" : true;
  LMSCommit(data: any): boolean | string {
    // TODO persist data to the backend via api
    return LMS.returnBooleanStrings ? "true" : true;
(window as any).API = new ScormAPI();

SCORM API – the data

When switching to a different page/lesson on the SCORM content, the SetValue method would be called with the below data. You can use this to track when they’re viewing each page, or you can bookmark this lesson, and when the content loads the next time, this bookmark will be fetched and loaded.


cmi.core.lesson_location index.html#/lessons/mtbaKxQ4RDu_YDJBFZvSMu2OIR6RxdxF cmi.core.lesson_location index.html#/lessons/39MLSElHJV1BSnoUDBwCH8fShFCCfWu5 cmi.core.lesson_location index.html#/lessons/-bF1Q7JhLliX3XfB9Q3V1nPVJsy_5c6d


Every 20 seconds the SetValue method would be called with the timestamp since the SCORM content was loaded and initialised. This can be used to track time spent on the content.


cmi.core.session_time 0000:00:20.0

cmi.core.session_time 0000:00:40.0

cmi.core.session_time 0000:01:00.0

cmi.core.session_time 0000:01:20.0

cmi.core.session_time 0000:01:40.0


When answering a question in a quiz, the SetValue method would be called with the below interaction data. This is very valuable as you can see how much detail it gives you about the question the learner interacted with, as well as their answer.

cmi.interactions._count Wellness_Quiz_Match_each_behavior_on_the_left_to_its_corresponding_impact_on_the_right._1 

cmi.interactions.0.type matching 

cmi.interactions.0.student_response Chronic_stress.Increased_blood_pressure,Lack_of_restful_sleep.Irritability,No_time_with_friends.Feelings_of_isolation 

cmi.interactions.0.correct_responses.0.pattern Chronic_stress.Increased_blood_pressure,Lack_of_restful_sleep.Irritability,No_time_with_friends.Feelings_of_isolation cmi.interactions.0.result correct cmi.interactions.0.weighting 1 cmi.interactions.0.latency 0000:00:12.28 0 

cmi.core.score.raw 100 

cmi.core.score.max 100 

cmi.core.score.min 0


In conclusion

SCORM is an extremely useful solution and standard to consider when looking at building an LMS. If not just to be compliant with the industry, you should also save a lot of development time, have the backing of an industry standard, and look good to your client in the process.

It is also important to remember that there are multiple versions of the SCORM standard (2004, 1.2, etc), and they work slightly differently. Furthermore, different authoring tools might export their SCORM files with a slightly different configuration. This should not matter if you have followed the SCORM standard properly,  i.e., correctly used the imsmanifest.xml and implemented the SCORM api as per the standard. 

If you intend to have multiple authoring tools feeding SCORMS into your LMS, make sure you test them all out properly! That is, however, a large undertaking and would entirely depend on the use case and scale of the LMS you are building. As always, budget, scope and timelines need to be taken into consideration.

Planning to build an app? 

Try our free software development calculator to maximise your ROI.

Request for Access to Information

The following forms are available to download with regards to request for access to information: