Problem Statement
Every 2.5 seconds a new website goes live, yet more than 1.2 billion people worldwide face barriers because many of those sites ignore WCAG 2.1 standards. Developers often run manual checks after a release, discovering critical failures only when users file complaints. The challenge is to catch accessibility violations the moment a page is rendered, and to provide actionable, context‑aware guidance without slowing down the user experience.
Axe-Core Foundations
Axe-core is the de‑facto open‑source engine for automated accessibility testing. It runs in the browser, returns a JSON payload of violations, and is maintained by Deque Systems. To embed it in a serverless workflow, you can use the axe-puppeteer wrapper, which launches a headless Chrome instance, injects axe, and extracts results.
const puppeteer = require("puppeteer");
const { axe } = require("axe-puppeteer");
async function runAxe(url) {
const browser = await puppeteer.launch({args: ["--no-sandbox"]});
const page = await browser.newPage();
await page.goto(url, {waitUntil: "networkidle2"});
const results = await new axe.Page(page).analyze();
await browser.close();
return results.violations;
}
module.exports = { runAxe };
The violations array contains each rule ID, a short description, and an array of nodes that failed. This raw data is perfect for downstream AI processing.
Adding AI Insight with OpenAI
OpenAI embeddings turn textual descriptions into high‑dimensional vectors that can be compared for similarity. By embedding the violation description together with a curated knowledge base of remediation patterns, the model can suggest the most relevant fix for each issue.
import os, openai, json
openai.api_key = os.getenv("OPENAI_API_KEY")
def get_fix_suggestion(violation):
prompt = f"Provide a concise remediation for this WCAG violation: {violation['description']}"
response = openai.Completion.create(
engine="gpt-3.5-turbo",
prompt=prompt,
max_tokens=120,
temperature=0.2,
)
return response.choices[0].text.strip()
# Example usage
violation = {"description": "Image elements must have alternate text"}
print(get_fix_suggestion(violation))
In practice you store the knowledge base in a vector database (e.g., Pinecone) and perform a nearest‑neighbor search. The serverless function merges axe results with the AI‑generated suggestions, producing a single JSON payload ready for the front‑end.
Serverless Deployment
Serverless platforms such as AWS Lambda, Vercel Edge Functions, or Cloudflare Workers let you run the audit on demand without provisioning servers. A typical Lambda runtime includes Node.js 18, which satisfies both puppeteer and the OpenAI SDK.
# System requirements
# - Node.js >=18
# - AWS CLI configured
# - OpenAI API key set in environment
# 1. Create a new Lambda function
aws lambda create-function \
--function-name ai-accessibility-auditor \
--runtime nodejs18.x \
--handler index.handler \
--zip-file fileb://function.zip \
--role arn:aws:iam::123456789012:role/lambda-exec-role
# 2. Add environment variables
aws lambda update-function-configuration \
--function-name ai-accessibility-auditor \
--environment Variables={OPENAI_API_KEY=your_key}
The handler receives a URL via HTTP POST, runs runAxe, enriches each violation with get_fix_suggestion, and returns the combined report. Because the audit runs in under 3 seconds for most pages, the endpoint can be called from a CI pipeline or a browser extension for real‑time feedback.
Putting It All Together
Below is a minimal Lambda entry point that orchestrates the pieces. It demonstrates error handling, timeout management, and response shaping.
const { runAxe } = require("./axeRunner");
const openai = require("openai");
openai.apiKey = process.env.OPENAI_API_KEY;
exports.handler = async (event) => {
try {
const { url } = JSON.parse(event.body);
const violations = await runAxe(url);
const enriched = await Promise.all(
violations.map(async (v) => {
const suggestion = await openai.Completion.create({
engine: "gpt-3.5-turbo",
prompt: `Provide a concise remediation for this WCAG violation: ${v.description}`,
max_tokens: 120,
temperature: 0.2,
});
return {...v, suggestion: suggestion.choices[0].text.trim()};
})
);
return {
statusCode: 200,
headers: {"Content-Type": "application/json"},
body: JSON.stringify({url, results: enriched})
};
} catch (err) {
console.error(err);
return {statusCode: 500, body: JSON.stringify({error: err.message})};
}
};
Deploy the zip containing index.js, axeRunner.js, and node_modules. Once live, a simple curl command demonstrates the real‑time audit:
curl -X POST https://your-api-id.execute-api.region.amazonaws.com/default/ai-accessibility-auditor \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'
The response includes each violation, the impacted selector, and a human‑readable fix suggestion generated by OpenAI, ready for developers to act on immediately.
Conclusion
By marrying axe‑core’s reliable rule engine with OpenAI’s natural‑language reasoning and a serverless execution model, you can deliver an AI‑powered, real‑time web accessibility auditor that fits into modern CI/CD workflows. The architecture scales on demand, costs under a few cents per audit, and most importantly, transforms raw violation data into actionable guidance, moving the web closer to inclusive design.
Sources
- Deque Systems – axe-core Documentation
- OpenAI API Reference
- AWS Lambda Developer Guide
Author: Mahmut Sarıkaya — sarikayadev.com