LiveAudit

CASOON Open Source

Accessibility inspection where the page actually runs.

One script tag on your own site, and findings appear on the affected element — in the page's real state, after every script, embed and client-side render has had its say.

MITself-hostedRust → WebAssemblyno runtime framework
index.htmlhtml
<!-- your own domain, your own copy: there is no CDN -->
<script type="module" src="/vendor/liveaudit/inspector.js"></script>
gzipped JavaScript, layer included
18.8 kB
gzipped WebAssembly, the whole rule set
80.9 kB
states a finding can have — never a score
4
attributes written to the inspected page
0

What makes it different

  1. Findings on the element, not beside it

    A report tells you that an image on some page has no alt text. The inspector layer puts the finding on that image, in the state the page is actually in — after hydration, after the third-party embed loaded, after the cookie banner appeared.

  2. Two axes, never a percentage

    Outcome says how certain the statement is: FAIL proven, REVIEW suspected, PASS passed, UNTESTED not decidable by machine. Severity says how much it weighs. A single number would hide exactly that difference, so there is none.

  3. "Not testable" is not "passed"

    A contrast rule without rendering access reads like a passed check in most tools. Here it is listed as not run, with the reason. Where it runs but cannot decide — text on a gradient has no single background colour to measure — it reports UNTESTED instead of a verdict.

  4. It inspects. It does not repair.

    No data attributes, no inline styles, no rewritten markup: the layer lives in its own host element and positions itself from measurements it reads. This is deliberately not an accessibility overlay: it makes no claim to repair anything.

  5. One rule set, three surfaces

    The rules live in the shared Rust core in barrierlab, which also drives astro-post-audit at build time and auditmysite in CI. A finding carries the same rule id in all three. That reuse — not speed — is why the core is Rust.

Quickstart

LiveAudit is self-hosted: you install it, copy two files into your own project and serve them from your own domain. A centrally hosted script would make someone else's domain a permanent dependency of your site.

  1. Install it: npm install @casoon/liveaudit — the package holds inspector.js and a11y_wasm_bg.wasm, built and ready.
  2. Copy both files next to each other into your own site and add the script tag. The module loads its WebAssembly from beside itself.
  3. Open the page with ?liveaudit. Without the flag the script registers nothing, creates no global and loads no WebAssembly.
  4. Call LiveAudit.show() from the console or from your own toolbar.
on the unlocked pagejs
// Nothing registers until the page is unlocked with ?liveaudit
await LiveAudit.show();                      // scan, then draw the layer
await LiveAudit.show(el, { rendering: true }); // with the contrast pass
LiveAudit.hide();                            // nothing of it stays behind

On npm, still self-hosted

@casoon/liveaudit carries the two built files, not the sources. Copy them from node_modules into your public directory at build time; updating is an ordinary dependency update, and nothing is loaded from anyone else's domain.

If your site has a strict Content Security Policy

Instantiating WebAssembly needs wasm-unsafe-eval inscript-src. Without it the inspector fails with an error that names the missing directive instead of failing silently.