Skip to content
🔍 Firefox Add-ons linter, written in JavaScript. 👁
JavaScript Shell
Branch: master
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Update CODEOWNERS Jan 10, 2020
bin Move internal scripts to separate folder (#2309) Dec 11, 2018
docs Refactor deprecated handling. (#2747) Sep 9, 2019
locale Pontoon: Update Norwegian Nynorsk (nn-NO) localization of AMO Linter Jan 15, 2020
scripts Fix errors Jul 15, 2019
src Update dependency chalk to v3 (#2907) Dec 16, 2019
tests Remove appveyor Oct 29, 2019
tmp Added .gitkeep Mar 3, 2018
.babelrc Switch to official babel-gettext-extractor lib (#2718) Jul 25, 2019
.eslintignore Move internal scripts to separate folder (#2309) Dec 11, 2018
.eslintrc Update eslint-config-amo, integrate Prettier and addons-frontend insp… Sep 4, 2018
.gitignore Add stale.yml and move github files (#2825) Oct 15, 2019
.npmignore chore(npmignore): Cleanup list of assets included in the released npm… Apr 5, 2018
.npmrc Force exact version pinning. Oct 11, 2018
.nvmrc Update Node.js to v10.18.1 Jan 9, 2020
.prettierignore Move internal scripts to separate folder (#2309) Dec 11, 2018
.prettierrc Fix errors Jul 15, 2019
.spelling Run markdown-spellcheck against README and docs Oct 16, 2018
.travis.yml Update Node.js to v10.18.1,v12.14.1 Jan 9, 2020
LICENSE Initial commit Sep 14, 2015 Update to node 10 Nov 18, 2019
config.js Move bn-BD to bn (Bengali) Jul 23, 2019
jest.config.js Replace setupTestFrameworkScriptFile with setupFilesAfterEnv Jun 23, 2019
jest.integration.config.js Fix lint Aug 20, 2019
package-lock.json Lock file maintenance Jan 21, 2020
package.json prepare 1.21.0 Jan 14, 2020
renovate.json Try to fix renovate `supportPolicy` definition. (#2958) Dec 5, 2019
webpack.config.js Update eslint-config-amo, integrate Prettier and addons-frontend insp… Sep 4, 2018
webpack.l10n.config.babel.js Fix lint Aug 20, 2019

Build Status codecov Dependency Status devDependency Status npm version


The Add-ons Linter is being used by web-ext and to lint WebExtensions.

It can also be used as a standalone binary and library.

You can find more information about the linter and it's implemented rules in our documentation.


Command Line

You need Node.js to use the add-ons linter.

To validate your add-on locally, install the linter from npm:

# Install globally so you can use the linter from any directory on
# your machine.
npm install -g addons-linter

After installation, run the linter and direct it to your add-on file:


Alternatively you can point it at a directory:

addons-linter my-addon/src/

The addons-linter will check your add-on and show you errors, warnings, and friendly messages for your add-on. If you want more info on the options you can enable/disable for the command-line app, use the --help option:

addons-linter --help

Linter API Usage

You can use the linter directly as a library to integrate it better into your development process.

import linter from 'addons-linter';

const sourceDir = process.cwd();

const linter = linter.createInstance({
  config: {
    // This mimics the first command line argument from yargs,
    // which should be the directory to the extension.
    _: [sourceDir],
    logLevel: process.env.VERBOSE ? 'debug' : 'fatal',
    stack: Boolean(process.env.VERBOSE),
    pretty: false,
    warningsAsErrors: false,
    metadata: false,
    output: 'none',
    boring: false,
    selfHosted: false,
    // Lint only the selected files
    //   scanFile: ['path/...', ...]
    // Exclude files:
    shouldScanFile: (fileName) => true,
  // This prevent the linter to exit the nodejs application
  runAsBinary: false,
  .then((linterResults) => ...)
  .catch((err) => console.error("addons-linter failure: ", err));

linter.output is composed by the following properties (the same of the 'json' report type):

  metadata: {...},
  summary: {
    error, notice, warning,
  error: [{
    type: "error",
    code, message, description,
    column, file, line
  }, ...],
  warning: [...],
  notice: [...]


If you'd like to help us develop the addons-linter, that's great! It's pretty easy to get started, you just need Node.js installed on your machine.

Quick Start

If you have Node.js installed, here's the quick start to getting your development dependencies installed and running the tests

git clone
cd addons-linter
npm install
# Run the test-suite and watch for changes. Use `npm run test-once` to
# just run it once.
npm run test

You can also build the addons-linter binary to test your changes.

npm run build
# Now run it against your add-on. Please note that for every change
# in the linter itself you'll have to re-build the linter.

Required Node version

addons-linter requires Node.js v10 or greater. Have a look at our .travis.yml file which Node.js versions we officially test.

Using nvm is probably the easiest way to manage multiple Node versions side by side. See nvm on GitHub for more details.

Install dependencies

Install dependencies with npm:

npm install

Dependencies are automatically kept up-to-date using renovatebot.

npm scripts

Script Description
npm test Runs the tests (watches for changes)
npm [run] build Builds the lib (used by Travis)
npm run test-coverage Runs the tests with coverage (watches for changes)
npm run test-once Runs the tests once
npm run lint Runs ESLint
npm run test-coverage-once Runs the tests once with coverage
npm run test-integration-linter Runs our integration test-suite
npm run prettier Automatically format the whole code-base with Prettier
npm run prettier-dev Automatically compare and format modified source files against the master branch


You can run npm build to build the library.

Once you build the library you can use the CLI in bin/addons-linter.


Run npm test. This will watch for file-changes and re-runs the test suite.


We're looking to maintain coverage at 100%. Use the coverage data in the test output to work out what lines aren't covered and ensure they're covered.

Assertions and testing APIs

We are using using Sinon for assertions, mocks, stubs and more see the Sinon docs for the API available.

Jest is being used as a test-runner but also provides helpful tools. Please make sure you read their documentation for more details.


We use pino for logging:

  • By default logging is off (level is set to 'fatal') .
  • Logging in tests can be enabled using an env var e.g: LOG_LEVEL=debug jest test
  • Logging on the CLI can be enabled with --log-level [level].


We use Prettier to automatically format our JavaScript code and stop all the on-going debates over styles. As a developer, you have to run it (with npm run prettier-dev) before submitting a Pull Request.


In a nutshell the way the linter works is to take an add-on package, extract the metadata from the xpi (zip) format and then process the files it finds through various content scanners.

We are heavily relying on ESLint for JavaScript linting, cheerio for HTML parsing as well as fluent.js for parsing language packs.


Each file-type has a scanner. For example: CSS files use CSSScanner; JavaScript files use JavaScriptScanner. Each scanner looks at relevant files and passes each file through a parser which then hands off to a set of rules that look for specific things.


Rules get exported via a single function in a single file. A rule can have private functions it uses internally, but rule code should not depend on another rule file and each rule file should export one rule.

Each rule function is passed data from the scanner in order to carry out the specific checks for that rule it returns a list of objects which are then made into message objects and are passed to the Collector.


The Collector is an in-memory store for all validation message objects "collected" as the contents of the package are processed.


Each message has a code which is also its key. It has a message which is a short outline of what the message represents, and a description which is more detail into why that message was logged. The type of the message is set as messages are added so that if necessary the same message could be an error or a warning for example.


Lastly when the processing is complete the linter will output the collected data as text or JSON.


We deploy to npm automatically using TravisCI. To release a new version, increment the version in package.json and create a PR. Make sure your version number conforms to the semver format eg: 0.2.1.

After merging the PR, create a new release with the same tag name as your new version. Once the build passes it will deploy. Magic!

You can’t perform that action at this time.