Validate newsletter templates the fast way. Point this tool at inline HTML, files, stdin, or URLs and it will tell you which features are accepted, partial, rejected, or unknown across the Can I Email dataset. Optional BFSG audits add a thin accessibility sanity check powered by Playwright + axe-core.
Pick the runtime that matches your workflow:
| Option | When to use it |
|---|---|
| CLI | Quick local checks; plug into any shell script |
| Java DSL | Keep validations inside JVM tests or build plugins |
| GitHub Action | Validate pull requests with zero scripting |
| Maven Central / GitHub Packages | Import as a library and embed the validator |
| Docker image | Containerized runs or CI systems without Java |
Each interface shares the same reporting core and produces JSON, XML, HTML, and Markdown artifacts.
./email-html-validator [OPTIONS] <HTML | FILE | URL | ->Grab the latest binary from the Releases page or build it
yourself via ./mvnw package. We publish:
email-html-validator.jar(portable JAR for any Java 21+ runtime)email-html-validator.native(Linux x64, Linux arm64, macOS x64/arm64, Windows x64 via GraalVM)- Docker image
ghcr.io/yunabraska/email-html-validator:<tag>
| Flag | Description |
|---|---|
--output-dir <dir> |
Folder for JSON/XML/HTML/Markdown reports (default ./reports) |
--no-bfsg |
Skip the BFSG accessibility audit |
--bfsg-tags <tag,...> |
Limit BFSG rules to comma-separated axe-core tags (e.g., wcag2aa,best-practice) |
--ignore-features <slug,...> |
Suppress noisy feature slugs (tag:html,tag:head,tag:body ignored by default) |
--github-summary |
Mirror the Markdown report to GITHUB_STEP_SUMMARY |
--playwright-version |
Print the bundled Playwright Java version and exit |
- Provide inline HTML, a path, an
http(s)URL, or-for stdin. - Exit codes:
0success,1usage/source error,2runtime/Playwright/BFSG failure. - Environment twins (e.g.,
EHV_OUTPUT_DIR,EHV_NO_BFSG,EHV_BFSG_TAGS,EHV_IGNORE_FEATURES,EHV_SUMMARY) let you drive the CLI from containers and Actions without long flag lists.
# JAR (all platforms)
java -jar email-html-validator.jar --output-dir reports "<html><body><table></table></body></html>"
# Native binary (Linux/macOS)
./email-html-validator.native template.html --no-bfsg --output-dir reports/native
# Windows
email-html-validator.exe template.html --bfsg
# Stream from stdin
cat template.html | ./email-html-validator.native - --no-bfsgEmbed validations inside tests or build plugins via EmailHtmlValidatorRequest:
import berlin.yuna.ehv.validation.EmailValidator;
import java.nio.file.Path;
import java.util.List;
var report = EmailValidator.html("<table data-hero></table>")
.bfsg(true)
.bfsgTags(List.of("wcag2aa", "best-practice"))
.ignoreFeatures(List.of("attribute:data-hero"))
.outputDirectory(Path.of("build/reports/email"))
.run();
var accepted = report.asBigDecimal("accepted");- The
run()call returns aTypeMapcontaining the same data as the CLI JSON report. - Call
disableReportExport()if you only want the in-memory payload.
Add the dependency from Maven Central (or GitHub Packages):
<dependency>
<groupId>berlin.yuna</groupId>
<artifactId>email-html-validator</artifactId>
<version>${email-html-validator.version}</version>
</dependency>Drop the Action into any workflow to fail builds when coverage falls short:
- name: "Validate HTML"
uses: YunaBraska/email-html-validator@main
with:
source: ${{ github.workspace }}/newsletter.html
output_dir: reports/ci
bfsg_tags: wcag2aa,best-practice
github_summary: trueOutputs (accepted, partial, rejected, bfsg_status, report_json, etc.) can feed follow-up steps. Provide source
as inline HTML, a repo path, or - for stdin.
Prefer to download from GitHub Packages? Add the repository plus dependency:
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/YunaBraska/email-html-validator</url>
</repository>
</repositories>
<dependency>
<groupId>berlin.yuna</groupId>
<artifactId>email-html-validator</artifactId>
<version>${email-html-validator.version}</version>
</dependency>Use your GITHUB_TOKEN (or a PAT) as the repo credential. The artifact exposes the same API used by the DSL example.
Run validations without installing Java:
docker run --rm \
-v "$PWD/reports:/reports" \
ghcr.io/yunabraska/email-html-validator:latest \
--output-dir /reports "<title>Ship it</title>"- Mount a host folder to collect the reports.
- Add
--no-bfsgif Playwright browsers are unavailable inside your environment. - Set
PLAYWRIGHT_CLI_DIRorEHV_*variables with-eto customize behavior.
Every interface writes the same artifacts:
| File | Purpose |
|---|---|
report.json |
Raw TypeMap serialized for automation |
report.xml |
Deterministic XML for XPath/XSLT pipelines |
report.html |
Shareable human report with percentages, notes, BFSG results |
report.md |
Markdown twin; appended to GitHub summaries when requested |
unknownFeatures, ignoredFeatures, BFSG issue counts, and partial client lists appear across all formats. The CLI and
Action also emit quick stats to GITHUB_OUTPUT (accepted, partial, rejected, bfsg_status, etc.).
Each JSON/XML/TypeMap payload contains:
accepted,partial,rejected– weighted percentagespartialNotes,unknownFeatures,ignoredFeatures,ignoredFeatureCountpartialClients,rejectedClients,featureCount,clientCount,operatingSystemCountbfsgStatus,bfsgIssueCount,bfsgIssues(when BFSG is enabled)playwrightVersion,caniemailUrl, and the exported file paths
- BFSG checks launch headless Chromium through the Playwright Java bindings shipped with the tool.
- Linux hosts need the dependencies listed in the Playwright CI guide.
When that’s not feasible, run the validator with
--no-bfsgorEHV_NO_BFSG=true. - Set
PLAYWRIGHT_CLI_DIR/EHV_PLAYWRIGHT_CLI_DIRwhen you install the Playwright driver bundle yourself (for example, in multi-stage Docker builds). The CLI exposes--playwright-versionso you can fetch matching artifacts.
Want to contribute or run the full suite locally?
./mvnw clean verify– build the JAR, run CLI black-box tests, regenerate fixtures../mvnw -q -DskipTests -Pnative package– build a GraalVM binary (target/email-html-validator.native).DockerfileandDockerfile_Nativeship the CLI/native images used for releases.- BFSG tests expect Playwright browsers. Install them once via
./mvnw -B -q exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install chromium --with-deps"or setPLAYWRIGHT_BROWSERS_PATHto a cached location. - The Can I Email dataset snapshot lives under
src/main/resources/caniemail. To regenerate, place upstream markdown files insrc/test/resources/caniemail/_featuresand runCaniEmailDatasetTest.
Questions, bugs, or feature ideas? Open an issue and mention how you run the validator (CLI, Action, Docker, etc.) so we can reproduce quickly.