pa11y is your automated accessibility testing pal


pa11y is your automated accessibility testing pal.
It runs HTML CodeSniffer from the command line for programmatic accessibility reporting.

Current Version: 1.7.0
Build Status:
Node Version Support: 0.10

pa11y requires Node.js 0.10+ and PhantomJS.

On a Mac, you can install these with Homebrew:

$ brew install node
$ brew install phantomjs

If you're on Linux, you'll probably be able to work it out.

Windows users approach with caution – we've been able to get pa11y running (Windows 7, Node 0.10) but only after installing Visual Studio and the Windows SDK (as well as Git, Python and PhantomJS). The Windows installation instructions for node-gyp are a good place to start.

Once you've got these dependencies, you can install pa11y globally with:

$ npm install -g pa11y

Once installed, the pa11y command should be available to you.

  Usage: pa11y [options] <url>
    -h, --help             output usage information
    -V, --version          output the version number
    -r, --reporter <name>  specify a reporter to use, one of: console (default), csv, json
    -s, --standard <name>  specify a standard to use, one of: Section508, WCAG2A, WCAG2AA (default), WCAG2AAA
    -c, --htmlcs <url>     specify a URL to source HTML_CodeSniffer from. Default:
    -C, --config <file>    specify a JSON config file for ignoring rules
    -t, --timeout <ms>     specify the number of milliseconds before a timeout error occurs. Default: 30000
    -u, --useragent <ua>   specify a useragent to use when loading your URL. Default: pa11y/<version>
    -v, --viewport <wxh>   specify the size of the browser viewport. Default: 640x480
    -p, --port <port>      specify the port to run the PhantomJS server on. Default: 12300
    -d, --debug            output debug messages
    --strict               upgrade warnings to errors for exit status
# Run pa11y with console reporting 
$ pa11y
# Run pa11y with CSV reporting and save to file 
$ pa11y -r csv > report.csv
# Run pa11y with the WCAG2AAA ruleset 
$ pa11y -s WCAG2AAA

You can also use pa11y from JavaScript by requiring the module directly. This will give you access to the pa11y.sniff function. The sniff function accepts two arguments, the first is an options object, the second is a callback:

var pa11y = require('pa11y');
pa11y.sniff(options, callback);

(string) The URL to sniff. Required.

(string,object) The reporter to use. This can be a string (see command-line usage) or an object (see custom reporters). Default null.

(string) The standard to use. One of Section508, WCAG2A, WCAG2AA, WCAG2AAA. Default WCAG2AA.

(string) The URL to source HTML_CodeSniffer from. Default

(string,object) The path to a JSON config file or a config object (see configuration). Default null.

(number) The number of milliseconds before a timeout error occurs. Default 30000.

(string) The user-agent to send with the request. Default pa11y/<version>.

(number) The port the PhantomJS server should run on. Default 12300.

(number) The viewport width to load the page at.

(number) The viewport height to load the page at.

(boolean) Whether to report debug-level messages. Default: false.

The callback function should accept two arguments. The first is an error object or null, the second is an object containing the results of the sniff.

// Sniff a URL 
    url: ''
}, function (errresults) {
    console.log(results); // output results object to console 
// Sniff a URL, specifying some options 
    url: '',
    standard: 'WCAG2AAA',
    timeout: 20000
}, function (errresults) {
    console.log(results); // output results object to console 
// Sniff a nonexistent URL 
    url: '$$$'
}, function (errresults) {
    console.log(err); // Error: URL could not be loaded 

pa11y can be configured via a JSON file or JavaScript object.

On the command line, specify a JSON configuration file with the --config flag:

$ pa11y --config ./config/pa11y.json

If you're using the JavaScript API, you can pass configurations in by either specifying a JSON file or passing in a config object directly:

    config: __dirname + '/config/pa11y.json'
    config: {}

The config file or object should be formatted like the example below, where

  • The cookies key is an array of maps containing only the required keys for PhantomJS cookie objects.
  • The ignore key holds an array of rule names you'd like to ignore. You can find the codes for each rule in the console output, so you can simply copy/paste these into your config. We also maintain a list of all available rules.
    "cookies": [
            "name": "cookie-name",
            "value": "cookie-value",
            "domain": "localhost"
    "ignore": [

All configuration options are optional.

pa11y can't catch all accessibility errors. It'll catch many of them, but you should do manual checking as well.

Also, due to HTML CodeSniffer being a graphical tool which highlights elements in the DOM, pa11y is most useful to use as a rough benchmark of how many errors/warnings your site has. The messages themselves don't hold much value outside of the browser yet. We're working on this, and if you have any suggestions then we'd be happy to chat!

Writing your own reporter for pa11y is easy, and will allow you to customise the output. This can be useful for integrating with your CI, producing human-readable reports, graphing, etc.

When a reporter is specified, the program will look for node modules with the name pa11y-reporter-<name>. So if you use the following option:

$ pa11y -r rainbows

then pa11y will attempt to load the module pa11y-reporter-rainbows.

Reporter modules export the following functions, which will be used by pa11y when that reporter is selected. All functions are optional, but you'll need to implement at least error and handleResult for the reporter to be functional.

exports.begin()                // Called before processing, used to output welcome messages or similar 
exports.log(str)               // Called with logging information 
exports.debug(str)             // Called with debug information if pa11y is run with the `-d` debug flag 
exports.error(str)             // Called with error information 
exports.handleResult(results)  // Called when results are available 
exports.end()                  // Called once everything is done, just before the process exits 

For example reporters, take a look at the built-in reporters or the rainbows reporter.

To develop pa11y, you'll need to clone the repo and install dependencies with npm install. You'll also need Grunt to be installed globally in order to run tests, you can do this with npm install -g grunt-cli.

Once you're set up, the following commands are available:

$ grunt       # Run the lint and test tasks together 
$ grunt lint  # Run JSHint with the correct config 
$ grunt test  # Run unit and functional tests 

Code with lint errors or failing tests will not be accepted, please use the build tools outlined above.

For users with push-access, don't commit to the master branch. Code should be in develop until it's ready to be released.

Copyright 2013 Nature Publishing Group.
pa11y is licensed under the GNU General Public License 3.0.