{"id":20085345,"url":"https://github.com/saasify-sh/ta11y","last_synced_at":"2025-10-19T13:54:35.054Z","repository":{"id":36944831,"uuid":"232587209","full_name":"saasify-sh/ta11y","owner":"saasify-sh","description":"Modern web accessibility audits. 💪","archived":false,"fork":false,"pushed_at":"2022-12-10T14:15:32.000Z","size":1520,"stargazers_count":43,"open_issues_count":30,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-17T18:34:01.220Z","etag":null,"topics":["a11y","a11y-testing","accessibility","accessibility-audits","accessibility-automation","accessibility-testing","ada","compliance","html-validation","saas","saas-api","wcag","wcag2","web"],"latest_commit_sha":null,"homepage":"https://ta11y.saasify.sh","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saasify-sh.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"contributing.md","funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-01-08T14:53:29.000Z","updated_at":"2025-02-23T22:34:59.000Z","dependencies_parsed_at":"2023-01-17T07:31:02.184Z","dependency_job_id":null,"html_url":"https://github.com/saasify-sh/ta11y","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saasify-sh%2Fta11y","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saasify-sh%2Fta11y/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saasify-sh%2Fta11y/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saasify-sh%2Fta11y/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saasify-sh","download_url":"https://codeload.github.com/saasify-sh/ta11y/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252604590,"owners_count":21775117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a11y","a11y-testing","accessibility","accessibility-audits","accessibility-automation","accessibility-testing","ada","compliance","html-validation","saas","saas-api","wcag","wcag2","web"],"created_at":"2024-11-13T15:55:42.148Z","updated_at":"2025-10-19T13:54:34.955Z","avatar_url":"https://github.com/saasify-sh.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://ta11y.saasify.sh\" title=\"ta11y\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/saasify-sh/ta11y/master/media/logo.svg?sanitize=true\" alt=\"ta11y Logo\" width=\"256\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# ta11y\n\n\u003e Modern web accessibility audits. 💪\n\n[![NPM](https://img.shields.io/npm/v/@ta11y/ta11y.svg)](https://www.npmjs.com/package/@ta11y/ta11y) [![Build Status](https://travis-ci.com/saasify-sh/ta11y.svg?branch=master)](https://travis-ci.com/saasify-sh/ta11y) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\n## Features\n\n- **Accessibility as a service**\n  - Audit your websites with a range of test suites including WCAG 2.0/2.1 A, AA, AAA, Section 508, HTML validation, as well as our own best practices.\n- **Flexible and automated**\n  - Run manual tests during development and then integrate into any CI pipeline. Supports generating reports in XLS, XLSX, CSV, JSON, HTML, and more.\n- **Runs in any environment**\n  - Easy integration that supports localhost, firewalls, custom auth, as well as any public production environment.\n- **Modern dynamic websites**\n  - Ta11y treats all websites as dynamic with full JavaScript support, so you'll test pages as your users actually experience them.\n- **Free to try**\n  - Simple to get started for free, then [sign up](/pricing) once you're ready to remove rate limits. Have a non-profit use case? [Get in touch](mailto:support@saasify.sh).\n- **Private \u0026 secure**\n  - Ta11y is built using serverless functions and never stores any of your data or audit results.\n\n## Usage\n\nThis project is broken down into the following packages:\n\n- [@ta11y/ta11y](./packages/ta11y) - Main CLI for running web accessibility audits with ta11y.\n- [@ta11y/core](./packages/ta11y-core) - Core library for programatically running web accessibility audits with ta11y.\n- [@ta11y/extract](./packages/ta11y-extract) - Library to crawl and extract content from websites.\n- [@ta11y/reporter](./packages/ta11y-reporter) - Library to convert audit results to different formats.\n\n## CLI\n\nThe easiest way to get started is via the CLI.\n\n```bash\nnpm install -g @ta11y/ta11y\n```\n\n```bash\nUsage: ta11y [options] \u003curl\u003e\n\nOptions:\n  -V, --version                  output the version number\n  -o, --output \u003cfile\u003e            Output the results to the given file (format determined by file\n                                 type). Supports xls, xlsx, csv, json, html, txt, etc.\n  -r, --remote                   Run all content extraction remotely (website must be publicly\n                                 accessible). Default is to run content extraction locally.\n                                 (default: false)\n  -e, --extract-only             Only run content extraction and disable auditing. (default: false)\n  -s, --suites \u003cstrings\u003e         Optional comma-separated array of test suites to run. (section508,\n                                 wcag2a, wcag2aa, wcag2aaa, best-practice, html). Defaults to\n                                 running all audit suites.\n  -c, --crawl                    Enable crawling additional pages. (default: false)\n  -d, --max-depth \u003cint\u003e          Maximum crawl depth. (default: 16)\n  -v, --max-visit \u003cint\u003e          Maximum number of pages to visit while crawling.\n  -S, --no-same-origin           By default, we only crawling links with the same origin as the\n                                 root. Disables this behavior so we crawl links with any origin.\n  -b, --blacklist \u003cstrings\u003e      Optional comma-separated array of URL glob patterns to ignore.\n  -w, --whitelist \u003cstrings\u003e      Optional comma-separated array of URL glob patterns to include.\n  -u, --user-agent \u003cstring\u003e      Optional user-agent override.\n  -e, --emulate-device \u003cstring\u003e  Optionally emulate a specific device type.\n  -H, --no-headless              Disables headless mode for puppeteer. Useful for debugging.\n  -P, --no-progress              Disables progress logging.\n  --api-key \u003cstring\u003e             Optional API key.\n  --api-base-url \u003cstring\u003e        Optional API base URL.\n  -h, --help                     output usage information\n```\n\n### Notes\n\n**The CLI defaults to running all crawling and content extraction locally via a headless Puppeteer instance**.\n\nYou can disable this and run everything remotely by passing the `--remote` option, though it's not recommended.\n\nSee [@ta11y/core](https://github.com/saasify-sh/ta11y/tree/master/packages/ta11y-core) for more detailed descriptions of how the different configuration options affect auditing behavior.\n\n### API Key\n\nThe free tier is subject to rate limits as well as a 60 second timeout, so if you're crawling a larger site, you're better off running content extraction locally.\n\nIf you're processing a non-publicly accessible website (like `localhost`), then you _must_ perform content extraction locally.\n\nYou can bypass rate limiting by [signing up](https://ta11y.saasify.sh/pricing) for an API key and passing it either via the `--api-key` flag or via the `TA11Y_API_KEY` environment variable.\n\nVisit [ta11y](https://ta11y.saasify.sh) once you're ready to sign up for an API key.\n\n### Output\n\nThe output format is determined by the file type if given a filename via `-o` or `--output`. If no file is given, the CLI defaults to logging the results in JSON format to `stdout`.\n\nTa11y supports a large number of [output formats](https://github.com/saasify-sh/ta11y/tree/master/packages/ta11y-reporter#formats) including:\n  - **xls**\n  - x**lsx**\n  - **csv**\n  - **json**\n  - **html**\n  - **txt**\n\nHere are some example audit results so you can get a feel for the data:\n  - [example.com](http://example.com/) single page audit: [csv](https://github.com/saasify-sh/ta11y/blob/master/media/example.csv), [json](https://github.com/saasify-sh/ta11y/blob/master/media/example.json), [xls](https://github.com/saasify-sh/ta11y/blob/master/media/example.xls?raw=true), [xlsx](https://github.com/saasify-sh/ta11y/blob/master/media/example.xlsx?raw=true)\n  - [Wikipedia](http://en.wikipedia.org) small crawl (`--max-visit 16`): [csv](https://github.com/saasify-sh/ta11y/blob/master/media/wikipedia.csv), [json](https://github.com/saasify-sh/ta11y/blob/master/media/wikipedia.json), [xls](https://github.com/saasify-sh/ta11y/blob/master/media/wikipedia.xls?raw=true), [xlsx](https://github.com/saasify-sh/ta11y/blob/master/media/wikipedia.xlsx?raw=true)\n\n### Examples\n\n\u003cdetails\u003e\n\u003csummary\u003eBasic single page audit\u003c/summary\u003e\n\nThis example runs all available audit test suites on the given URL.\n\nIt uses the default output behavior which logs the results in JSON format to `stdout`.\n\n```bash\nta11y https://example.com\n```\n\n```json\n{\n  \"summary\": {\n    \"errors\": 4,\n    \"warnings\": 0,\n    \"infos\": 2,\n    \"numPages\": 1,\n    \"numPagesPass\": 0,\n    \"numPagesFail\": 1\n  },\n  \"results\": {\n    \"https://example.com\": {\n      \"url\": \"https://example.com\",\n      \"depth\": 0,\n      \"rules\": [\n        {\n          \"id\": \"html\",\n          \"description\": \"A document must not include both a “meta” element with an “http-equiv” attribute whose value is “content-type”, and a “meta” element with a “charset” attribute.\",\n          \"context\": \"f-8\\\"\u003e\\n    \u003cmeta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\"\u003e\\n    \u003c\",\n          \"type\": \"error\",\n          \"tags\": [\n            \"html\"\n          ],\n          \"firstColumn\": 5,\n          \"lastLine\": 5,\n          \"lastColumn\": 71\n        },\n        ...\n      ],\n      \"summary\": {\n        \"errors\": 4,\n        \"warnings\": 0,\n        \"infos\": 2,\n        \"pass\": false\n      }\n    }\n  }\n}\n```\n\nIf you only want specific audit results, use the `--suite` option.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eBasic single page audit writing results to an Excel file\u003c/summary\u003e\n\nThis example runs the wcag2a and wcag2aa audit test suites on the given URL and outputs the results to an Excel spreadsheet (supports any `xls`, `xlsx`, or `csv` file).\n\n```bash\nta11y https://example.com -o audit.xls\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSingle page audit testing WCAG2A and WCAG2AA writing results to a CSV file\u003c/summary\u003e\n\nThis example runs wcag2a and wcag2aa audit test suites on the given URL and outputs the results to a comma-separated-value file (`csv`).\n\n```bash\nta11y https://example.com --suites wcag2a,wcag2aa -o audit.csv\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eBasic single page content extraction\u003c/summary\u003e\n\n```bash\nta11y https://example.com --extract-only\n```\n\n```json\n{\n  \"results\": {\n    \"https://example.com\": {\n      \"url\": \"https://example.com\",\n      \"depth\": 0,\n      \"content\": \"\u003c!DOCTYPE html\u003e\u003chtml\u003e\u003chead\u003e\\n    \u003ctitle\u003eExample Domain\u003c/title\u003e\\n\\n    \u003cmeta charset=\\\"utf-8\\\"\u003e\\n    \u003cmeta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\"\u003e\\n    \u003cmeta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\"\u003e\\n    \u003cstyle type=\\\"text/css\\\"\u003e\\n    body {\\n        background-color: #f0f0f2;\\n        margin: 0;\\n        padding: 0;\\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \\\"Segoe UI\\\", \\\"Open Sans\\\", \\\"Helvetica Neue\\\", Helvetica, Arial, sans-serif;\\n        \\n    }\\n    div {\\n        width: 600px;\\n        margin: 5em auto;\\n        padding: 2em;\\n        background-color: #fdfdff;\\n        border-radius: 0.5em;\\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\\n    }\\n    a:link, a:visited {\\n        color: #38488f;\\n        text-decoration: none;\\n    }\\n    @media (max-width: 700px) {\\n        div {\\n            margin: 0 auto;\\n            width: auto;\\n        }\\n    }\\n    \u003c/style\u003e    \\n\u003c/head\u003e\\n\\n\u003cbody\u003e\\n\u003cdiv\u003e\\n    \u003ch1\u003eExample Domain\u003c/h1\u003e\\n    \u003cp\u003eThis domain is for use in illustrative examples in documents. You may use this\\n    domain in literature without prior coordination or asking for permission.\u003c/p\u003e\\n    \u003cp\u003e\u003ca href=\\\"https://www.iana.org/domains/example\\\"\u003eMore information...\u003c/a\u003e\u003c/p\u003e\\n\u003c/div\u003e\\n\\n\\n\u003c/body\u003e\u003c/html\u003e\"\n    }\n  },\n  \"summary\": {\n    \"root\": \"https://example.com\",\n    \"visited\": 1,\n    \"success\": 1,\n    \"error\": 0\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCrawl part of a site and audit each page\u003c/summary\u003e\n\n```bash\nta11y https://en.wikipedia.org --crawl --max-depth 1 --max-visit 8\n```\n\nThis example will crawl and extract the target site locally and then perform a full remote audit of the results. You can use the `--remote` flag to force the whole process to operate remotely.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCrawl a localhost site and audit each page\u003c/summary\u003e\n\n```bash\nta11y http://localhost:3000 --crawl\n```\n\nThis example will crawl all pages of a local site and then perform an audit of the results.\n\nNote that the local site does not have to be publicly accessible as content extraction happens locally.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eRun a WCAG2AA audit on a localhost site\u003c/summary\u003e\n\n```bash\nta11y http://localhost:3000 --crawl --suites wcag2aa\n```\n\nThis example will crawl all pages of a local site and then perform an audit of the results, **only considering the WCAG2AA test suite**.\n\nNote that the local site does not have to be publicly accessible as content extraction happens locally.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSingle page audit using WCAG2A and HTML validation test suites\u003c/summary\u003e\n\n```bash\nta11y https://example.com --suites wcag2a,html\n```\n\n```json\n{\n  \"summary\": {\n    \"suites\": [\n      \"wcag2a\",\n      \"html\"\n    ],\n    \"errors\": 2,\n    \"warnings\": 0,\n    \"infos\": 2,\n    \"numPages\": 1,\n    \"numPagesPass\": 0,\n    \"numPagesFail\": 1\n  },\n  \"results\": {\n    \"https://example.com\": {\n      \"url\": \"https://example.com\",\n      \"depth\": 0,\n      \"rules\": [\n        {\n          \"id\": \"html\",\n          \"description\": \"A document must not include both a “meta” element with an “http-equiv” attribute whose value is “content-type”, and a “meta” element with a “charset” attribute.\",\n          \"context\": \"f-8\\\"\u003e\\n    \u003cmeta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\"\u003e\\n    \u003c\",\n          \"type\": \"error\",\n          \"tags\": [\n            \"html\"\n          ],\n          \"firstColumn\": 5,\n          \"lastLine\": 5,\n          \"lastColumn\": 71\n        },\n        {\n          \"id\": \"html\",\n          \"description\": \" The “type” attribute for the “style” element is not needed and should be omitted.\",\n          \"context\": \"e=1\\\"\u003e\\n    \u003cstyle type=\\\"text/css\\\"\u003e\\n    b\",\n          \"type\": \"info\",\n          \"tags\": [\n            \"html\"\n          ],\n          \"firstColumn\": 5,\n          \"lastLine\": 7,\n          \"lastColumn\": 27\n        },\n        {\n          \"id\": \"html\",\n          \"description\": \"Consider adding a “lang” attribute to the “html” start tag to declare the language of this document.\",\n          \"context\": \"TYPE html\u003e\u003chtml\u003e\u003chead\u003e\",\n          \"type\": \"info\",\n          \"tags\": [\n            \"html\"\n          ],\n          \"firstColumn\": 16,\n          \"lastLine\": 1,\n          \"lastColumn\": 21\n        },\n        {\n          \"id\": \"html-has-lang\",\n          \"type\": \"error\",\n          \"description\": \"Ensures every HTML document has a lang attribute\",\n          \"impact\": \"serious\",\n          \"tags\": [\n            \"cat.language\",\n            \"wcag2a\",\n            \"wcag311\"\n          ],\n          \"help\": \"\u003chtml\u003e element must have a lang attribute\",\n          \"helpUrl\": \"https://dequeuniversity.com/rules/ta11y/3.4/html-has-lang?application=Ta11y%20API\"\n        }\n      ],\n      \"summary\": {\n        \"errors\": 2,\n        \"warnings\": 0,\n        \"infos\": 2,\n        \"pass\": false\n      }\n    }\n  }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eMore advanced crawling with debug output\u003c/summary\u003e\n\nThis example crawls the English Wikipedia site, visiting up to 200 pages and uses a whitelist to ensure that we only consider links on the English Wikipedia domain.\n\nIt then runs an audit against the `wcag2a` and `wcag2aa` test suites.\n\nThis example also shows how you can get additional debug output during crawling and auditing that can be really helpful to understand what's going on under the hood.\n\n```bash\nDEBUG=ta11y:* ta11y \"https://en.wikipedia.org\" --crawl --max-visit 200 --whitelist \"https://en.wikipedia.org/**/*\" --suites wcag2a,wcag2aa -o wikipedia.xlsx\n```\n\u003c/details\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://ta11y.saasify.sh\" title=\"ta11y\"\u003e\n    \u003cimg src=\"https://storage.googleapis.com/saasify-uploads-prod/c5480c7c4e006629b4a2f7bfc5b783e2fce662ec.jpeg\" alt=\"ta11y Logo\" /\u003e\n  \u003c/a\u003e\n  \u003cspan\u003eHelp us with our goal of building a more accessible and inclusive web. ☺️\u003c/span\u003e\n\u003c/p\u003e\n\n## License\n\nMIT © [Saasify](https://saasify.sh)\n\nSupport my OSS work by \u003ca href=\"https://twitter.com/transitive_bs\"\u003efollowing me on twitter \u003cimg src=\"https://storage.googleapis.com/saasify-assets/twitter-logo.svg\" alt=\"twitter\" height=\"24px\" align=\"center\"\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaasify-sh%2Fta11y","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaasify-sh%2Fta11y","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaasify-sh%2Fta11y/lists"}