Skip to content

QuasarThe document engine that never throws.

Fall in

Any text goes in. A valid tree comes out.

Quasar parses BBCode into an immutable syntax tree, re-parses only what an edit touched, and turns every broken tag into a diagnostic with a fix. It is the engine inside Miliastry, and the text is always the truth: nothing it does rewrites a character the author did not touch.

  • Zero runtime dependencies
  • Browser, Node.js, Bun, Deno and Tauri
  • Three dialects: osu, miliastry and lyne
2,400+
tests in the engine’s own suite
144,000
fuzzed edits checked against a full parse
0
divergences found in them
0
runtime dependencies

Miliastry is the editor. Quasar is what it understands.

Every part of Miliastry that reads your page reads it through Quasar: the same tree, the same rules, the same answer. That is why the preview never disagrees with what osu! publishes, why the Error Checker points at the exact characters, and why the visual editor can change one word without rewriting your code.

156 source files across Miliastry import it.

Code editor

Tag colours, completion and the document outline come from the engine’s own tag tables.

osu! preview

osu!’s pairing and newline rules, patched block by block as you type.

Error Checker

Every problem and every lightbulb fix is a diagnostic from the analyzer.

Visual editor

Blocks and the canvas edit the tree and write minimal changes back.

Text Studio

Gradients, rainbows and waves, baked into BBCode by the effects toolkit.

Export

What you publish comes from the exporter, which cannot even reach the renderer.

Anchors

Boxes you open in the preview stay open as you type: anchors follow the text.

This page

Every preview and output on it was rendered by the engine.

One source of truth

The code pane, the preview and the canvas are views of one tree. None of them keeps a copy that could drift.

The text is always the truth

A click in the visual editor becomes the smallest possible edit to your BBCode. Your spacing and casing survive.

What you see is what osu! shows

The preview reproduces osu!’s own parser, so a page that looks right here looks right on your profile.

Anatomy of a keystroke.

What happens between you pressing a key and Miliastry showing the result, on a page of any size.

  1. 1

    One edit

    The editor hands Quasar exactly what changed: where it starts, where it ends, and the new text. Nothing else.

  2. 2

    A window, not the page

    Quasar re-parses a small window around the edit. Every node outside it is kept as the very same object.

  3. 3

    Positions, lazily

    The red tree on top shifts positions only when someone asks. Ids stay stable, so anchors and open boxes follow the text.

  4. 4

    Diagnostics for the window

    The analyzer re-checks what changed. A tag left open becomes a warning, with its fix attached.

  5. 5

    One block repainted

    The osu! preview patches only the block that changed. Everything else on screen stays the same DOM.

Write the worst BBCode you can.

This is the real engine, loaded into your browser. Every keystroke is applied as an edit, re-parsed incrementally and timed on your machine.

Source

Pulling the engine in…

full parse
—
analysis
—
nodes
—
Problems
—

Or let chaos type for you.

Throws random tag soup at the parser, a thousand documents at a time, right here.

0
documents parsed
0
exceptions thrown
—
total time
Last input…

One tree. Every output.

Parse once in Miliastry’s dialect, then write it out however the destination needs it. osu! has no gradient tag, so the exporter paints one colour per letter.

Sourcemiliastry
[centre][size=150][gradient=#ffe4b8,#ffb35c,#ff6d5a]Quasar[/gradient][/size][/centre]
[box=What it does]
[list]
[*][b]Parses[/b] anything
[*][i]Never[/i] throws
[/list]
[/box]
[centre][size=150][color=#FFE4B8]Q[/color][color=#FFD093]u[/color][color=#FFBD6E]a[/color][color=#FFA55C]s[/color][color=#FF895B]a[/color][color=#FF6D5A]r[/color][/size][/centre]
[box=What it does]
[list]
[*][b]Parses[/b] anything
[*][i]Never[/i] throws
[/list]
[/box]

And it reads the other way too.

Markdown, HTML and MilHibri are imported into the same tree, so they export to BBCode like anything else.

Markdown
# Hello, osu!

Some **bold**, some _italic_ and a [link](https://osu.ppy.sh).

- one
- two
osu! BBCode
[heading]Hello, osu![/heading]
Some [b]bold[/b], some [i]italic[/i] and a [url=https://osu.ppy.sh]link[/url].
[list][*]one[*]two[/list]

Smaller, and not one pixel different.

The optimizer finds markup that changes nothing on screen and removes it, with every edit planned together so no two fight over the same characters.

Before0 characters saved
  • Remove redundant nested [bold]
  • Unwrap colour around whitespace
  • #ff0000 → #f00
  • Merge 2 × [color=#ff0000]
  • #ffcc00 → #fc0
  • Remove empty [italic]

Fast enough to disappear.

Typing re-parses a window around the edit and reuses the rest of the tree. Measured on a 547 KB document, against the 16.7 ms a frame lasts at 60 Hz.

  • A keystroke in prose0.3 ms
  • Random keystroke, median0.89 ms
  • Random keystroke, 90th percentile2.02 ms
  • Random keystroke, 99th percentile28.6 ms
  • Full rebuild≈ 55 ms
96.4% of real typing on the 65-document Miliastry corpus is handled incrementally. A repeated analysis with no edit costs nothing: it used to cost 65 ms.

Everything an editor needs, on one tree.

One tree, and every service an editor wants built on top of it. Everything is exported from the package root.

Syntax tree

Immutable green nodes shared across edits, red nodes on top with parents, ranges and stable ids.

GreenNodeRedNode

Incremental parsing

Re-parses a window around each edit and reuses everything outside it.

applyChangeIncrementalParser

Diagnostics and fixes

Unclosed, crossed and unknown tags, unsafe URLs and osu! pitfalls, each with a quick fix or a Fix All.

queryLightbulbfixAll

osu! fidelity

osu!’s own tag pairing and newline rules, with a preview that patches the DOM block by block.

OsuPreviewTreepairing: 'osu'

WYSIWYG canvas

A contenteditable whose bold, Enter and paste become minimal edits that keep the author’s spacing.

CanvasDocument

Render and export

HTML with osu! and Lyne themes, SVG, BBCode per dialect, Markdown, JSON and Tiptap.

HTMLRendererBBCodeExporter

Text effects

Gradients, rainbows and waves baked into BBCode, mixed in OKLab.

evaluateEffectmixHexOklab

Anchors and collaboration

Ranges that follow the text through edits and reloads, and transforms for a text CRDT.

AnchorSettransformRange

Every promise has an enforcer.

A guarantee nothing enforces is a hope. Each of these is held by the type system, a constructor, the tree validator or a property test.

PromiseEnforced by
No input throws. Nesting past 256 levels stays text, with a warning.20,000 levels of nesting in seven shapes, through every phase
Every text leaf holds exactly the characters its range covers.The tree validator, after every rebuild and re-parse
An incremental re-parse builds the tree a full parse would.144,000 fuzzed edits, 0 divergences
Publishing never depends on presentation.A test that walks the whole import graph
An automatic fix never changes what the reader sees.Every automatic finding on the corpus, rendered before and after
An anchor never moves silently.80 fuzzed seeds, 0 silent errors

Questions you might have.

Short answers, with the number or the file that backs each one.

  1. Is Quasar the same as Quasar Framework?

    No. Quasar Framework is a Vue.js UI framework, maintained by another project. Quasar here is a BBCode document engine written in TypeScript by Miliastry: a parser, an analyzer, a formatter and an exporter. They share a name and nothing else.

  2. Is Miliastry just a BBCode editor?

    No. Miliastry is a windowed creative studio for osu! userpages. The code editor, the visual canvas, the osu! preview, Text Studio and the workspace are views of one document, and BBCode is the format it speaks, not the product.

  3. What makes Quasar a document engine instead of a BBCode parser?

    A parser turns text into a tree. Quasar also owns the tree: immutable green nodes shared across edits, red nodes with parents, ranges and stable ids, incremental re-parsing, diagnostics with fixes, anchors that survive edits, and exporters to osu! BBCode, Markdown, JSON, HTML and Tiptap. Editors are built on top of it, not inside it.

  4. Does it throw on malformed input?

    No. Any text parses to a valid tree: unclosed tags, crossed tags, unknown tags and 20,000 levels of nesting all stay text, with a warning. A page can never break the editor.

  5. Which BBCode dialects does it support?

    Three: osu, with osu!’s own tag set and pairing rules; miliastry, the superset the studio edits in; and lyne, the theme used to render pages. Each exporter targets one dialect, so a gradient osu! has no tag for is painted one colour per letter.

  6. How fast is an edit?

    On a 547 KB document, 0.30 ms per keystroke in prose and a 0.89 ms median on random edits, against the 16.7 ms of a frame at 60 Hz. 96.4% of real typing on the 65-document Miliastry corpus is handled incrementally, and a repeated analysis with no edit costs nothing.

  7. Does it run in the browser?

    Yes. It is pure TypeScript with zero runtime dependencies and runs in the browser, Node.js, Bun, Deno and Tauri. The playground on this page imports the real engine after first paint and fuzzes a thousand documents in your tab.

  8. How much of Miliastry is built on it?

    156 source files import @miliastry/quasar. The code editor, the osu! preview, the Error Checker, the visual canvas, Text Studio, anchors and export all read and write through the same tree, which is why they cannot disagree with each other.

  9. How is it licensed?

    Source-available under the Miliastry Source License (MSL-1.1). The source, the tests and the docs are public at github.com/AegleWorks/quasar-engine.

  10. How do I install it?

    From GitHub Packages: add @miliastry:registry=https://npm.pkg.github.com/ to .npmrc, then npm install @miliastry/quasar. Three lines go from text to a tree: new BBCodeDocumentModel({ source, dialect }), doc.applyChange(...), and new BBCodeExporter({ target: 'osu' }).export(doc.redRoot).

Three lines to a tree.

Inside the Miliastry monorepo it is the @miliastry/quasar workspace. Anywhere else, install it from GitHub Packages.

  1. Add the registry to .npmrc
    @miliastry:registry=https://npm.pkg.github.com/
  2. Install
    npm install @miliastry/quasar
Parse, read, edit, exportexample.ts
import { BBCodeDocumentModel, BBCodeExporter } from '@miliastry/quasar'

const doc = new BBCodeDocumentModel({
  source: '[b]Hello[/b] [color=#ff0000]world',
  dialect: 'osu',
})

doc.toHTML()
// <span class="bb-paragraph"><strong>Hello</strong> …</span>

doc.diagnostics?.items
// [{ severity: 'warning', code: 'unclosed-tag', … }]

doc.applyChange({ start: 3, end: 8, text: 'Hi' })

new BBCodeExporter({ target: 'osu' }).export(doc.redRoot!)
// [b]Hi[/b] [color=#ff0000]world[/color]

The whole engine, its tests and its docs are on GitHub. Or open Miliastry and watch it run under an editor.

github.com/AegleWorks/quasar-engine

Source-available under the Miliastry Source License (MSL-1.1).