Inspect where the page
actually runs
LiveAudit is an embedded accessibility inspector: one script tag on your own site, findings on the affected element rather than in a separate report. The shared rule core is published; the browser layer is being built.
{ "rule_id": "images/alt-suspicious", "outcome": "review", "severity": "medium", "message": "Der Alt-Text „foto1.jpg" beschreibt das Bild vermutlich nicht.", "location": { "node": "1843" }, "wcag": ["1.1.1"] }
Status as of 2026-09-18
Architecture decided
Three layers: TypeScript collects the DOM, Rust evaluates, TypeScript displays. Decisions and limits are documented in the repository.
Approach validated
Five real documents from 1,244 to 723,613 nodes measured. Crossing into WASM costs 0.5 ms at 31,000 nodes — the bottleneck is elsewhere.
a11y-core published
Four crates on crates.io: a11y-report, a11y-dom, accname, a11y-rules. One rule set serves build time, CI and the live page.
Collector and WASM binding
The live DOM is materialised into WASM memory once, then Rust evaluates. Prototype measured; production version open.
Inspector layer
Frames, markers and a side panel above the page — without modifying the inspected subtree.
Contrast, focus, live mode
Checks that need rendering data or real interaction: contrast, tab order, target size, mutating DOM.
A report tells you what.
The page shows you where.
Conventional tools produce a list that sits beside the page. Working through it means locating the element again every time. LiveAudit inverts that: the finding sits on the element, on the page, in its real state after every script and embed has run.
Concept and decisions →- 01Runs on the page itself — no re-render, no second engine
- 02Does not modify the inspected subtree: no attributes, no inline styles
- 03Inspects, does not repair — explicitly not an accessibility overlay
- 04Built for developers, not as a substitute for manual testing
A percentage hides
what you need to know
FAIL
Detected automatically. The rule could prove the problem — an alt is missing, an ID occurs twice.
REVIEW
Suspected heuristically. An alt text exists but looks like a filename. Needs a human decision.
PASS
Passed. Kept internally but not shown by default — otherwise the actual findings drown.
UNTESTED
Not decidable automatically. Produces an item on a manual checklist instead of a verdict that is not one.
„Did not run" is not
„passed"
A contrast check without rendering access reads like a passed check in most tools. LiveAudit records separately whether a rule could run at all, and why not.
The same finding,
wherever it comes from
{
"rule_id": "images/alt-suspicious",
"outcome": "review",
"severity": "medium",
"message": "Der Alt-Text „foto1.jpg" beschreibt
das Bild vermutlich nicht.",
"location": { "node": "1843" },
"wcag": ["1.1.1"]
}{
"rule_id": "contrast/text",
"not_run": "capability_missing",
"reason": "Host liefert keine Rendering-Werte"
}The same rule IDs
from build to live page
A finding has the same name in the build, in CI and in the browser. That is the actual reason for the Rust core — not speed.
- Build time
astro-post-audit
Reads the generated HTML after every
astro build. Structure and semantics, no browser. - CI and crawl
auditmysite
Drives Chrome remotely and uses its native accessibility tree. Adds rendering and interaction.
- Live page
LiveAudit
Sits inside the page. Can dispatch real events and observe a mutating DOM.
Automation ends
at a clear line
These areas are not reliably automatable. LiveAudit reports them as UNTESTED with a checklist instead of claiming a verdict.
Screen reader experience
A technically correct document can still be hard to operate.
Content quality
Whether an alt text describes the image adequately, or a link text works in context, is a human call.
Reading order
The technical tab order is determinable. Whether it makes sense is not.
Complex widgets
ARIA syntax is checkable. Whether a widget behaves sensibly for screen readers only shows in testing with one.
Usable today, even
without the finished tool
use a11y_dom::Arena;
use a11y_rules::run;
let report = run(&dokument);
// Gefunden: Bild ohne Alternativtext.
assert!(report.findings.iter()
.any(|f| f.rule_id == "images/alt-missing"));
// Nicht beurteilt: Regeln, für die dieser Host
// keine Rolle und keinen Namen liefert.
assert_eq!(report.summary.rules_not_run, 4);use accname::{name, IdIndex};
// <span id="l">Vorname</span>
// <input aria-labelledby="l">
let ids = IdIndex::build(dokument.root());
assert_eq!(name(feld, &ids).as_deref(), Some("Vorname"));Four crates on crates.io
a11y-report
Finding and report model. Two axes: state and severity.
Cratea11y-dom
Document model plus capability tiers. Rules run across different substrates.
Crateaccname
Accessible name and role per WAI-ARIA and HTML-AAM. Written against the specification.
Cratea11y-rules
The rules themselves, generic over the document model. 13 structural, 4 semantic.
at 31,000 nodes
at 31,000 nodes
gzipped
document measured
What LiveAudit is
and is not
Is this an accessibility overlay?
No. Overlay vendors promise to repair a page via JavaScript. LiveAudit inspects and changes nothing about the page — it shows findings in its own layer above it.
Can I use it today?
Not yet. The shared rule core is published as Rust crates and usable; the browser binding and the display are being built. The status above shows what is done.
How is it different from a browser extension?
An extension has to be installed by every person inspecting. LiveAudit is embedded by the site owner — so it also works in a preview, on staging or inside a CMS, without anyone installing anything.
Does it replace manual testing?
No, and it does not pretend to. Whatever cannot be reliably automated is reported as `UNTESTED` and lands on a checklist instead of in a pass statistic.
Why Rust and WASM?
So that the same rule set runs in the build, in CI and in the browser, and findings are named the same everywhere. The measurement showed that speed is not the argument — reuse is.
Same core,
different surface
Follow development in the open
Concept, architecture decisions, measurements and the published core are all public. MIT licensed.