# A11ySignal — Accessibility scans as a pipeline

> My own product: a scheduled WCAG 2.2 AA monitor. It crawls every page of a site in headless Chromium with axe-core, diffs each scan against the last one, and alerts only on what changed, with the element, the rule and the criterion. Public, on paid plans, running on my own server.

- Source: https://ivankarpinskyi.dev/work/a11ysignal

- Role: Founder, sole engineer and operator
- Year: 2026
- Status: Own product · public · paid plans
- Live: https://a11ysignal.com

## § 01 A monitor, not an audit

An audit is a snapshot, and the site keeps changing. A11ySignal scans on a schedule and reports only what changed since the last scan. The European Accessibility Act made this a standing question for sites that sell in the EU.

## § 02 A scan is a queue of jobs

_Fig. 1: A11ySignal: one diff drives every output._

Scans run as BullMQ jobs on Redis with at-least-once delivery, so every handler is idempotent on the scan id. One scan per site at a time, and a fixed number of browsers on one server. A failure is recorded with a reason and retried only when it is transient.

## § 03 Findings as a diff

Findings are normalised per rule, page and selector. The diff between two scans is computed once and drives the alerts, the dashboard and the API, so the three never disagree. The score formula is published.

## § 04 What it outputs

1. **REST API**: With keys and rate limits.
2. **A CLI that fails a CI build**: When new issues appear.
3. **PDF reports and EN 301 549 statements**: In four languages.

## § 05 Plans enforced in one place

Plan limits live in one guard layer that both the dashboard and the public API go through.

## Stack

Next.js · NestJS · TypeScript · PostgreSQL + Prisma · BullMQ + Redis · Playwright + axe-core · Tailwind CSS · Resend · Paddle · Hetzner

## Related notes

- [Dual writes will bite you: choosing between a polling outbox and CDC](https://ivankarpinskyi.dev/blog/outbox-vs-dual-writes.md) (2026-10-06, Decision): A dual write has no safe ordering. How polling outboxes skip rows and bloat, how CDC slots fill disks, and how to pick the relay your team can run.
