Skip to content

Integration Overview

QTI Editor is a composable authoring kit built on ProseMirror. It ships as a set of focused packages that add QTI interaction types, commands, and serialization on top of a standard ProseMirror instance. There is no proprietary editor core to embed — your application owns the DOM and lifecycle; the QTI packages slot in as descriptors, plugins, and node specs.

The canonical integration shape is qti-example-editor, a minimal pure-ProseMirror QTI roundtrip editor. The TypeScript Integration guide walks through that shape file by file.

The layer model

LayerWhat it isRequired
ProseMirrorDocument model, view, and transaction systemYes
@citolab/prose-qtiDescriptor registry, all QTI interactions, item roundtripYes
@citolab/prose-extensionsGeneric ProseMirror extensions (block selection, node attrs sync, etc.)Optional

What you assemble

The boilerplate splits its editor across three files:

  • schema.ts — the document topology. Each interaction’s qti*InteractionNodeSpec is spread into one literal Schema with explicit content and group rules.
  • prosemirror-qti.ts — the QTI integration layer. Imports each *InteractionDescriptor explicitly, derives the qtiPlugins array and editableAttrs allowlist from them, and exposes the importItemFromUrl / exportItemXml roundtrip helpers from @citolab/prose-qti/item-roundtrip.
  • main.ts — the composition root. new EditorView(...) + EditorState.create({ doc, plugins }), with qtiPlugins ordered before the list-split and keymap(baseKeymap) so the QTI Enter/Backspace overrides win and unhandled keys fall through. It also wires the opt-in editor decorations — hover boundary, add/remove buttons, and a settings pill that dispatches an event for the host’s own attributes panel to handle.

qti-components

QTI Editor depends on @qti-components/* for the underlying QTI web components that render and encapsulate interaction behavior at runtime. @citolab/prose-qti pulls in the required @qti-components dependencies automatically.

Guide