npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lxpack/runtime

v0.7.0

Published

Web-native course runtime for LXPack

Readme

@lxpack/runtime

Documentation npm version CI License Node.js

Browser runtime for LXPack courses — lesson navigation, markdown and HTML lessons, component widgets, branching flow, quiz engine, progress tracking, and SCORM 1.2 / 2004 integration.

Part of LXPack. Docs: Lesson types · Tracking and completion · Branching.

| Related | Package | |---------|---------| | CLI / preview | @lxpack/cli | | Programmatic build | @lxpack/api | | Validation & bundles | @lxpack/validators | | Export shell | @lxpack/scorm | | UI widgets | @lxpack/components | | Track event types | @lxpack/tracking-schema |

Install

npm install @lxpack/runtime

Requires Node.js 18 or 20 (18+) for the build toolchain. Published bundles run in modern browsers (ESM client.js).

Package exports

| Import | Description | |--------|-------------| | @lxpack/runtime | Node/build-time API (LxpackRuntime, flow, variables, SCORM helpers, progress serialization, types) | | @lxpack/runtime/client | Self-contained browser bundle (dist/client.js) | | dist/styles.css | Bundled with the client in SCORM/standalone exports |

Browser client

Authoring HTML labs: Building interactions. Quizzes: Quizzes and assessments.

The CLI and SCORM packager embed @lxpack/runtime/client into exported courses. The client:

  • Renders markdown lessons, HTML interaction folders, type: spa lessons (iframe to path/index.html), and type: component lessons (via window.__LXPACK_COMPONENTS__)
  • Applies optional manifest.runtime.cssVariables as CSS custom properties on the learner shell root
  • Resolves next/previous navigation with the flow engine when course.yaml defines flow; otherwise linear lesson order
  • Loads assessments from embedded config (assessments, answerKeys, configs, feedback); does not fetch author YAML in production exports
  • Renders quizzes with renderAssessment() — single-select (radio) or multi-select (checkbox) MCQ, retakes, choice shuffle, and feedback modes from per-assessment config
  • Tracks lesson completion, manifest variables (v: prefix in suspend data), and assessment scores
  • Persists progress via SCORM suspend_data / CMI (compact JSON, size-safe) or localStorage in preview mode

Config is injected by the packager using safeJsonForHtml from @lxpack/scorm.

SPA lessons and bridge API

SPA lessons load in an iframe. Embedded apps should call the parent bridge (not window.lxpack inside the iframe):

window.parent?.lxpackBridge?.v1?.completeLesson("phishing_101");
window.parent?.lxpackBridge?.v1?.submitAssessment({
  id: "final_quiz",
  score: 0.9,
  passingScore: 0.7,
  passed: true,
});
window.parent?.lxpackBridge?.v1?.track({ type: "interaction", id: "clicked", data: { ok: true } });

Custom lesson renderers can register on window.__LXPACK_LESSON_RENDERERS__ before the client boots.

Flow and variables

import {
  evaluateCondition,
  resolveFlowGoto,
  resolveNextActivityId,
  initManifestVariables,
  readManifestVariable,
  writeManifestVariable,
} from "@lxpack/runtime";

| Module | Role | |--------|------| | flow.ts | Condition evaluation (variable.eq, assessment.passed, interaction.done, all / any) and goto resolution | | variables.ts | Manifest variable defaults and v: namespaced storage in progress |

LxpackRuntime exposes setVariable() / getVariable() on the learner API when the manifest declares variables.

Quiz module

import {
  renderAssessment,
  scoreAssessmentForm,
  getAttemptCount,
  shuffleQuestions,
} from "@lxpack/runtime";
// Re-exported from client as scoreAssessment

Supports maxAttempts, shuffleChoices, and showFeedback (immediate | end | never) from the build-time assessment bundle.

Multi-select scoring

When the answer key contains string[] for a question (or selectionMode: multiple), the UI renders checkboxes. Scoring per question:

  • Single-select: 0 or 1 (unchanged)
  • Multi-select: partial credit = (correct choices selected) ÷ (total correct choices); 0 if any incorrect choice is selected
  • Assessment score: average across all questions (mixed single- and multi-select assessments use the same aggregation)
  • Pass: score >= passingScore (0–1 fraction on the whole assessment)

Multi-select questions require an explicit Submit assessment click; immediate per-choice feedback applies only to radio (single-select) questions.

SCORM 1.2

import {
  findLmsApi,
  createScormConnection,
  installScormAPI,
  Scorm12Adapter,
  Scorm12Simulator,
  SCORM_SUSPEND_DATA_MAX,
} from "@lxpack/runtime";

| API | Description | |-----|-------------| | findLmsApi() | Walk parent/opener frames to locate the LMS SCORM 1.2 API | | createScormConnection(mode) | LMS adapter (scorm12) or local simulator (preview) | | installScormAPI() | Expose the simulator API on window for preview servers | | trimSuspendData(data) | Truncate suspend data to SCORM_SUSPEND_DATA_MAX (4096) |

SCORM 2004

import {
  findScorm2004Api,
  createScorm2004Connection,
  Scorm2004Adapter,
  Scorm2004Simulator,
} from "@lxpack/runtime";

| API | Description | |-----|-------------| | findScorm2004Api() | Locate API_1484_11 in parent/opener frames | | createScorm2004Connection(mode) | LMS adapter (scorm2004) or preview simulator | | CMI mapping | Progress and completion mapped for multi-SCO packages |

Use mode: "scorm2004" in RuntimeConfig when embedding the runtime in SCORM 2004 launch pages.

Runtime class

import { LxpackRuntime, type RuntimeConfig } from "@lxpack/runtime";

const runtime = new LxpackRuntime({
  manifest,
  mode: "scorm12", // "scorm2004" | "preview"
});

runtime.completeLesson("intro");
runtime.getAPI().setVariable("track", "advanced");
runtime.getAPI().submitAssessment("quiz", 0.85, 0.7);
runtime.getProgress();
runtime.terminate();

LxpackAPI methods include track(), submitAssessment(), getProgress(), and setVariable() / getVariable(). Call runtime.terminate() once when tearing down a SCORM session (guarded against double finish).

Build output

| Artifact | Role | |----------|------| | dist/client.js | Vite browser bundle (embedded in packages) | | dist/runtime.js | Node/library entry | | dist/styles.css | Runtime styles | | dist/*.d.ts | Type declarations |

Development

From the monorepo root:

pnpm --filter @lxpack/runtime build
pnpm --filter @lxpack/runtime test
pnpm --filter @lxpack/runtime typecheck

Links

License

Apache-2.0