GuidesAccessibility and the EAA · Published 9 Jun 2026 · Updated 2 Sep 2026 · toolkit.bot

EPUB Accessibility Checker: ACE by DAISY, EPUBCheck, and Pagina — and How to Read an ACE Report

If your organization needs EPUB files that satisfy WCAG 2.2 AA, Section 508, or the European Accessibility Act, you need to validate them. Three tools dominate the workflow: ACE by DAISY, EPUBCheck, and Pagina EPUB Checker. Here's what each actually catches — and what it misses.

Why automated checking isn't enough

Automated EPUB checkers can flag structural issues — missing alt attributes, heading order violations, missing language declarations. But they cannot determine whether alt text is meaningful, whether reading order matches visual order, or whether a table's headers convey the right semantics. A passing automated check does not mean your EPUB is accessible — it means it cleared the machine-checkable rules.

ACE by DAISY (free, open source)

What it checks:

Output: HTML report with pass/fail/warning per rule, screenshots of flagged content. Also exports JSON and EARL for pipeline integration.

How to run:

npm install -g @daisy/ace
ace --outdir ./ace-report your-book.epub

What it misses: Reading order issues not reflected in markup order, meaningful alt text quality, complex table semantics, logical structure beyond heading nesting.

Installing and running ACE

ACE needs Node.js 14 or later. After npm install -g @daisy/ace, confirm with ace --version. Useful options and a batch loop:

# custom report title, verbose, or silent
ace --outdir ./report --title "Annual Report 2025" ./annual-report.epub
ace --verbose --outdir ./report ./document.epub
ace --silent --outdir ./report ./document.epub

# validate every EPUB in a folder (Linux/macOS)
for f in *.epub; do ace --outdir "./reports/${f%.epub}" "$f"; done
# cross-platform batch in Python
import subprocess, pathlib

for epub in pathlib.Path("./epubs").glob("*.epub"):
    out = pathlib.Path("./ace-reports") / epub.stem
    r = subprocess.run(["ace", "--outdir", str(out), str(epub)], capture_output=True, text=True)
    print(f"{epub.name}: {'PASS' if r.returncode == 0 else 'FAIL'}")

Reading the report

ACE writes report.html (human-readable) and report.json (for pipelines) into --outdir. The HTML has three sections: a summary (conformance claim, declared accessibility features, violation counts by level), a violations table (criterion, impact from critical to minor, file and element, help link) and the package metadata. The entries you will meet most:

WCAG 1.4.10 Reflow — IMPACT: critical
LOCATION: EPUB/content/chapter01.xhtml (css-fixed-size)
# causes: fixed width CSS (width: 600px instead of max-width), a pre-paginated
# rendition:layout declaration in the OPF, absolutely positioned fixed-size elements

WCAG 1.1.1 Non-text Content — IMPACT: critical
LOCATION: EPUB/images/figure1.xhtml img[src="figure1.png"]
# fix: alt="Description of figure"; decorative: alt="" role="presentation"

WCAG 1.3.1 Info and Relationships — IMPACT: serious
LOCATION: EPUB/content/intro.xhtml .chapter-title
# fix: <h1>Chapter Title</h1>, not <p class="chapter-title">

A passing package also declares its conformance: schema:accessibilitySummary, schema:accessMode, schema:accessModeSufficient and dcterms:conformsTo (“EPUB Accessibility 1.1 - WCAG 2.1 Level AA”). An EPUB3 converted from PDF by toolkit.bot is reflowable, so the 1.4.10 row stays empty.

ACE as a CI/CD quality gate

ACE exits 0 on success and non-zero on failures, so a pipeline can block non-conforming EPUBs:

# GitHub Actions
name: EPUB Accessibility Check
on:
  push:
    paths: ['**.epub']
jobs:
  ace-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm install -g @daisy/ace
      - run: for f in dist/*.epub; do ace --outdir "reports/${f%.epub}" "$f"; done
      - uses: actions/upload-artifact@v4
        with: { name: ace-reports, path: reports/ }

EPUBCheck (free, W3C reference validator)

What it checks:

Not an accessibility checker — EPUBCheck validates structural and specification conformance, not WCAG. Run it first to ensure a valid EPUB, then run ACE for accessibility.

java -jar epubcheck.jar your-book.epub

Pagina EPUB Checker (browser-based)

Pagina offers a free online EPUB checker at accessibility-checker.pagina.gmbh. It combines EPUBCheck and ACE in a single drag-and-drop interface. No install required — useful for one-off checks or when you can't run Node.js locally.

Limitation: upload size is restricted on the free tier; large EPUBs may time out.

Section 508 and EAA requirements

For Section 508 (US federal agencies and contractors): EPUB files must conform to WCAG 2.0 AA as a minimum. ACE + manual screen-reader review (NVDA/JAWS on Windows, VoiceOver on Mac) is the standard workflow. ACE gives you the automated baseline; screen-reader testing catches the rest.

For the European Accessibility Act (EAA 2026): WCAG 2.2 AA is required for digital products and services. EPUB3 with proper semantic markup satisfies EAA requirements by design in ways that PDF cannot. Full EAA compliance guide →

Using ACE reports as compliance evidence

The ACE HTML report is suitable documentation for three audiences. For the EAA, it evidences WCAG conformance including 1.4.10 for national market surveillance authorities. For distributors, Ingram, Kobo and Apple Books are moving toward requiring EPUB Accessibility 1.1 metadata, and the report confirms it is set. For your accessibility statement, reference it directly:

Key publications are available in accessible EPUB3 format conforming to EPUB Accessibility 1.1 (WCAG 2.1 AA). ACE by DAISY validation reports are available on request.

What toolkit.bot outputs

All EPUBs generated by toolkit.bot target EPUB Accessibility 1.1:

Run ACE on any toolkit.bot output — it should pass all automated rules. If you find a failure, report it and we'll fix it.

Generate accessible EPUBs from your PDFs — free, no account required.

Convert PDF to EPUB →

Related guides