Installation
QTI Editor is split into focused packages so you only install what you need. The qti-prosemirror-item boilerplate is the reference shape; this page lists the packages it uses and how to install them.
Install
pnpm add prosemirror-state prosemirror-view prosemirror-model prosemirror-commands \ prosemirror-keymap prosemirror-history prosemirror-dropcursor prosemirror-gapcursor \ prosemirror-menu prosemirror-schema-basic prosemirror-schema-list prosemirror-tables \ @citolab/prose-qti @citolab/prose-extensions| Package | Purpose |
|---|---|
prosemirror-* | Core ProseMirror runtime, keymaps, history, cursors, menu bar, lists, tables |
@citolab/prose-qti | QTI descriptors, node specs, plugins, item roundtrip |
@citolab/prose-extensions | Generic ProseMirror plugins (block select, node attrs sync, semantic paste, …) |
@citolab/prose-qti treats the ProseMirror packages as peer dependencies. Keep the ProseMirror packages on one aligned release set and upgrade them together; reuse versions your app already has rather than introducing a second copy.
Stylesheet
Import @citolab/prose-qti/core-css.css wherever your app renders the editor’s document — it is a mandatory plain-CSS stylesheet (no Tailwind or PostCSS plugins required) that styles interaction element backgrounds, spacing, and the rubric-block boundary:
@import '@citolab/prose-qti/core-css.css';Pair it with the upstream @qti-components/theme stylesheet that styles the QTI web components themselves. See apps/qti-prosemirror-item/src/app.css for the reference import order.
QTI interactions
Each interaction has its own subpath. Import the descriptor and node spec explicitly per interaction — see the TypeScript Integration guide for the full shape.
| Subpath | Interaction type |
|---|---|
@citolab/prose-qti/components/choice | <qti-choice-interaction> |
@citolab/prose-qti/components/extended-text | <qti-extended-text-interaction> |
@citolab/prose-qti/components/text-entry | <qti-text-entry-interaction> |
@citolab/prose-qti/components/inline-choice | <qti-inline-choice-interaction> |
@citolab/prose-qti/components/hottext | <qti-hottext-interaction> |
@citolab/prose-qti/components/order | <qti-order-interaction> |
@citolab/prose-qti/components/match | <qti-match-interaction> |
@citolab/prose-qti/components/associate | <qti-associate-interaction> |
@citolab/prose-qti/components/gap-match | <qti-gap-match-interaction> |
@citolab/prose-qti/components/select-point | <qti-select-point-interaction> |
@citolab/prose-qti/components/rubric-block | <qti-rubric-block> |
@citolab/prose-qti/components/shared | Shared building blocks (qti-prompt, qti-simple-choice, …) |
Each interaction subpath exports:
*InteractionDescriptor—tagName,insertCommand,enterCommand,backspaceCommand,pluginFactories,attributePanelMetadata,nodeSpecsqti*InteractionNodeSpec— ProseMirror node spec (also reachable viadescriptor.nodeSpecs)register.js— side-effect module that defines the interaction’s Lit custom element
Custom elements are registered through side-effect imports per interaction (@citolab/prose-qti/components/<name>/register.js) plus the shared elements you use (@citolab/prose-qti/components/shared/components/qti-simple-choice/register.js, …).
Item roundtrip
@citolab/prose-qti/item-roundtrip exposes the import/export bridge:
import { importItemFromUrl, exportItemXml } from '@citolab/prose-qti/item-roundtrip';
const doc = await importItemFromUrl(href, schema);const xml = exportItemXml(view.state.doc, schema);See the QTI Item Roundtrip reference for the full surface.
Package overview
| Package | What it provides | When to use this |
|---|---|---|
prosemirror-* | Core ProseMirror runtime | Always — QTI Editor is built on ProseMirror. |
@citolab/prose-qti | Descriptors, interactions, node specs, plugins, item roundtrip | The main runtime. |
@citolab/prose-extensions | Generic ProseMirror plugins | When you want block selection, node attribute sync, semantic paste, etc. |
@citolab/prose-qti/qti3-item-import | Standard QTI 3.0 item normalization | When you need to ingest third-party QTI XML before parsing into the editor. |
@citolab/prose-qti/item-roundtrip | One-call import/export between ProseMirror and QTI item XML | When you want a single helper for the full QTI item roundtrip. |