Skip to content

Astrolabe

Open-source TypeScript building blocks for interactive exercises. Write HTML with answers, play it in an accessible player, and grade it in the browser or on your server.

This exercise runs in this page. Type an answer, pick one, then press "Check". The engine compiles the source in your browser and grades it there; nothing is sent anywhere.

exercise.html
<astl-doc lang="en">
<p>An elephant is <astl-gap id="g1" answer="grey"><astl-alt>gray</astl-alt></astl-gap>.</p>
<astl-choice id="q1">
<astl-prompt>How many legs does a spider have?</astl-prompt>
<astl-option id="a" correct>Eight</astl-option>
<astl-option id="b">Six</astl-option>
</astl-choice>
</astl-doc>

An elephant is gray.

How many legs does a spider have? Eight Six

The source is plain HTML with the answers in it: answer on the gap, correct on the option. The engine turns it into a public view without answers and a private answer key, so the same file also works with a backend that keeps the answers on the server.

HTML with answers

One script tag, no backend. The page compiles and grades in the browser, so the answers are in the page source. Good for homework pages, blogs and quick practice. Start here.

HTML + backend

Your server compiles the source, keeps the answer key and serves only the view. The player grades through two JSON endpoints. Good for tests and anything with stakes. Start here.

An editor, or yours

<astl-editor> adds an insert menu, an inspector, live issues and a preview to TipTap, or to the editor you already use through one small adapter. Start here.

Your own components

A component is one folder: a manifest, a definition, an element, an editor descriptor and messages. Nothing in the core changes. Start here.

Package What it does
astrolabe Everything on by default: astrolabe/engine, /player, /editor and /server with every built-in, and the script-tag bundles in dist/cdn/ (astrolabe.js grades in the browser, astrolabe-player.js plays views graded by a server, astrolabe-editor.js is the editor).
@astrolabe/core Contracts (TypeScript interfaces) and the i18n runtime. No dependencies.
@astrolabe/engine Parse, sanitise, validate, compile (view, answer key, metadata) and grade. Runs in browsers, Node, Deno, Bun and Workers.
@astrolabe/server The grading endpoint (check and submit) on the standard Fetch API.
@astrolabe/player <astl-player>: pages, practice and test modes, snapshots, accessible chrome. No answer logic.
@astrolabe/editor The authoring kit for any WYSIWYG editor: insert menu, inspector, issues, preview and a textarea adapter. No WYSIWYG engine.
@astrolabe/editor-tiptap <astl-editor>: the kit around a TipTap surface, loaded only when no other editor is plugged in.
@astrolabe/components The six built-in components, one folder per type.
@astrolabe/tokens Neutral --astl-* design tokens with light, dark and high-contrast themes, and the built-in looks playful and notebook.
@astrolabe/devkit The astl CLI: validate, compile, conformance.
  • Contracts first. Every boundary is a TypeScript interface in @astrolabe/core; implementations are swappable. See Contracts.
  • One schema per component. The manifest drives sanitising, validation, the view, the player, the editor and the generated reference.
  • Answers never leak by accident. Views carry no answers, ids are opaque, results carry no key data.
  • Accessible and multilingual from day one. WCAG 2.2 AA, keyboard alternatives, ICU plurals; the UI language and the content language are separate.
  • No lock-in. No framework and no backend is required, and TipTap only loads when no other editor is plugged in.