This project provides two major capabilities:
- QTI 2.x Players β Production-ready item and assessment players with extensibility and theming
- PIE β QTI Transformation Framework β Bidirectional transforms between QTI 2.2 and PIE, with CLI, web app, and IMS Content Package support
π Live Examples
Project Status: QTI 2.x players are production-ready. Transform framework is under active development. See STATUS.md for details.
PIE (Portable Interactions and Elements) is a complete framework for playing and authoring assessment items, maintained by Renaissance Learning with implementation partner MCRO.
Many Renaissance partners exchange content in QTI format, so bidirectional QTI β PIE transformation is essential. This project open sources that transformation framework for partners and the broader community.
We also built a spec-complete QTI 2.x player because a modern, open-source option was missingβand we needed one for previewing, analysis, and "convert then render" workflows.
Status: Production-ready
Full-featured players for rendering QTI 2.x assessment content in the browser.
Renders and scores individual QTI items:
- 21 interaction types β All QTI 2.2 interactions supported
- 45 response processing operators β Complete client-side scoring
- Role-based rendering β Candidate, scorer, author, tutor, proctor, testConstructor
- Adaptive items β Multi-attempt workflows with progressive feedback
- Accessible β Full keyboard navigation and screen reader support (follows WCAG 2.2 Level AA guidelines)
- Iframe isolation mode β Optional secure rendering for untrusted content
Orchestrates multi-item assessments:
- Navigation modes β Linear (sequential) and nonlinear (free navigation)
- Sections & hierarchy β Nested sections with rubric blocks
- Selection & ordering β Random item selection and shuffling per QTI spec
- Time limits β Countdown timers with warnings and auto-submission
- Item session control β Max attempts, review/skip, response validation
- State persistence β Auto-save with resume capability
- Outcome processing β Scoring templates (total, weighted, percentage, pass/fail)
- Backend adapter β Optional server-side scoring and secure data handling
The player architecture separates QTI logic from UI rendering:
- Plugin system (
QTIPlugin) β Register custom extractors, components, and lifecycle hooks - Registries β Priority-based
ExtractionRegistryandComponentRegistry - Typesetting hook β Host-provided math rendering (KaTeX adapter included)
- Custom operators β Support for
<customOperator>elements
See the ACME Likert plugin for a complete extensibility example.
Components render via web components (Shadow DOM) with a CSS variable contract:
- Theme tokens β DaisyUI-compatible variables (
--p,--a,--b1,--bc, etc.) ::part()hooks β Stable part names for host-side style refinement- Zero-CSS fallback β Components render correctly with no host styles
See STYLING.md for the full styling contract.
The player UI supports multiple languages with runtime locale switching:
- Type-safe translations β TypeScript autocomplete for all message keys
- Runtime switching β Change language without page reload
- Small bundle β <10 KB gzipped (core + default locale)
See @pie-qti/qti2-i18n for the complete i18n API and migration guide.
Status: Under active development
Bidirectional transformation between QTI 2.2 XML and PIE JSON.
QTI β PIE (@pie-qti/qti2-to-pie)
- Lossless round-trip when QTI originated from PIE
- Best-effort semantic transformation otherwise
- Vendor extension system for custom QTI variants
PIE β QTI (@pie-qti/pie-to-qti2)
- Lossless reconstruction when PIE contains embedded QTI
- Generator registry for custom PIE model handling
- IMS Content Package generation (
imsmanifest.xml)
Interactive web UI for transformations:
- Upload β Single files or ZIP packages (including nested ZIPs)
- Analyze β Discover items, count interactions, report issues
- Transform β Batch convert with progress reporting
- Preview β Side-by-side QTI and PIE rendering
The app uses sessionized local filesystem storage by default, but the architecture supports custom backend adapters.
Command-line tool for batch operations:
# Transform a single item
bun run pie-qti -- transform input.xml --format qti22:pie --output output.json
# Analyze QTI content
bun run pie-qti -- analyze ./content-package/
# See all commands
bun run pie-qti -- --help# Install dependencies
bun install
# Build all packages
bun run build
# Run tests
bun run test
# Lint and typecheck
bun run lint
bun run typecheck
# E2E tests (Playwright)
bun run test:e2eTo test with pie-players locally, clone both repos side-by-side. The postinstall script auto-links them.
bun run build:pages
bun run preview:pages
# Open http://localhost:4173/pie-qti/- Architecture Guide β System design, package map, extensibility, theming, and security
- Item Player β API, interactions, accessibility
- Assessment Player β Navigation, scoring, backend integration
- Styling Contract β Theming with CSS variables and ::part
- Example App β Demo application with all interactions
- Transformation Guide β Bidirectional transform overview
- Transform App β Web UI for transformations
- CLI β Command-line batch operations
- QTI β PIE β QTI to PIE transformer
- PIE β QTI β PIE to QTI transformer
- IMS Content Packages β Manifest generation
- Custom Generators β Adding PIE model support
- ACME Likert Plugin β Player extensibility example
ISC License β see LICENSE

