Getting started with web-ext
web-ext
is a command-line tool designed to speed up and simplify development. This article explains how to install and use web-ext
.
web-ext
is a command-line tool designed to speed up and simplify development. This article explains how to install and use web-ext
.
web-ext
is a Node-based application. You install it with brew
or the NodeJS npm
tool.
Install with brew
using:
brew install web-ext
Install with npm
using:
npm install --global web-ext
web-ext
requires the current LTS (long-term support) versions of NodeJS.
To test whether the installation worked, run the following command, which displays the web-ext
version number:
web-ext --version
web-ext
notifies you when a new version is available. To update, use the same commands as you did to install:
brew install web-ext
or
npm install --global web-ext
Before you use web-ext
, locate an example extension. If you don’t have one, use one from the webextensions-examples repo. If you want to start from scratch, use the community-developed boilerplating tool to start with a fresh extension.
Before trying out your extension with the run
command or submitting your package to addons.mozilla.org, use the lint
command to ensure your manifest and other source files are error-free. If you set strict_min_version
in your extension’s manifest file, lint reports on the permissions, manifest keys, and web extension APIs used that are not available in that version.
To check your extension code, cd
into your extension’s root directory and enter:
web-ext lint
This uses the addons-linter library to walk through your source code directory and report any errors, such as declaring an unknown permission.
See the lint reference guide to learn more.
In this section, learn how to:
Test an extension in Firefox by cd
'ing into your extension’s root directory and entering:
web-ext run
This starts Firefox and loads the extension temporarily in the browser, just as you can on the about:debugging
page. Note that this web-ext
method has the same limitations regarding prompts for permissions and restart features as about:debugging
.
See the run reference guide to learn more.
The run
command watches your source files and tells Firefox to reload the extension after you edit and save a file. For example, if you change the name
property in your manifest.json
file, Firefox displays the new name. This makes it easy to try out new features because you can see the effect immediately. The automatic reloading feature is active by default. You use it like this:
web-ext run
You can also press the r
key in the web-ext
terminal to trigger an extension reload.
If you experience unexpected behavior with the reloading feature, please file a bug. You can also disable reloading like this:
web-ext run --no-reload
Extension reloading is only supported in Firefox 49 or higher.
To run your extension in a version of Firefox Desktop other than the default, use the --firefox
option to specify a full path to the binary file. Here is an example for Mac OS:
web-ext run --firefox=/Applications/FirefoxNightly.app/Contents/MacOS/firefox-bin
On Windows, the path needs to include firefox.exe
, for example:
web-ext run --firefox="C:\Program Files\Mozilla Firefox\firefox.exe"
See the run command reference to learn more.
To run your extension in Firefox for Android, follow the instructions to set up your computer and device.
With your device connected to your development computer, run:
web-ext run --target=firefox-android
This command displays the device ID for your connected Android device or devices. If you don't see a device ID, check that you set up the device correctly for development.
Now, add the device ID to the command:
web-ext run --target=firefox-android --android-device=<device ID>
If you've installed multiple versions of Firefox on the device, choose one like this:
web-ext run --target=firefox-android ... --firefox-apk=org.mozilla.firefox
The first time you run this command, you may need to grant Android permissions for the APK. This is because the command needs read/write access to the device storage so that Firefox for Android can run on a temporary profile. The web-ext
output guides you on how to grant these permissions.
The web-ext
command does not alter your Firefox for Android preferences or data. To learn more about how web-ext
interacts with your device, run the command with --verbose
.
See the run command reference to learn more.
When using web-ext run
to test an extension on Firefox for Android, you see a message like this in the console output:
You can connect to this Android device on TCP port 51499
This is a remote debugger port that you can connect to with Firefox's developer tools. In this case, you connect to host localhost
on port 51499
.
See the Debug your extension guide for more information about debugging an extension on Firefox for Android.
When you execute web-ext run, the extension is installed and remains installed until you close Firefox. This does not violate any signing restrictions. If instead you create a zip file with web-ext build and try to install it into Firefox, you see an error telling you that the add-on is not signed. To install unsigned extensions, use an unbranded build or development build.
By default, the run
command creates a temporary Firefox profile. To run your extension with a specific profile use the --firefox-profile
option, like this:
web-ext run --firefox-profile=your-custom-profile
This option accepts a string containing the name of your profile or an absolute path to the profile directory. This is helpful if you want to configure settings for the run
command.
The run
command does not save any changes made to the custom profile specified by --firefox-profile
. To keep changes, use the --keep-profile-changes
option:
web-ext run --keep-profile-changes --firefox-profile=your-custom-profile
This may be helpful if your extension has many different run states.
This option makes destructive changes to the profile that are required for web-ext
to operate. It turns off auto-updates and allows silent remote connections, among other things. These changes make the profile insecure for daily use.
In this section learn how to:
After testing your extension and verifying that it's working, you can turn it into a package for submitting to addons.mozilla.org
using this command:
web-ext build
This outputs a full path to the generated .zip
file that can be loaded into a browser.
The generated .zip
file doesn't work on Firefox without signing or adding browser_specific_settings.gecko.id
key into manifest.json
. For more information, please refer to the WebExtensions and the Add-on ID page.
web-ext build
is designed to ignore files that are commonly not wanted in packages, such as .git
, node_modules
, and other artifacts.
See the build reference guide to learn more.
When you have confirmed that your extension works as expected, you can publish it on addons.mozilla.org. You can do this using the website or web-ext sign
. To use web-ext sign
you need to:
browser_specific_settings.gecko.id
.Metadata is required for the first version of an extension listed on AMO. This metadata can include any of the properties of the addons.mozilla.org add-on API Create request JSON object. However, the"categories"
and "summary"
properties must be provided.
For example:
{
"version": { "license": "MPL-2.0" },
"categories": { "firefox": ["shopping", "bookmarks"] },
"contributions_url": "https://donate.mozilla.org",
"requires_payment": false,
"homepage": {
"en-US": "http://example.org?lang=en-US",
"fr": "http://example.org?lang=fr"
},
"support_email": {
"en-US": "support@example.org",
"fr": "support-fr@example.org"
}
}
Visit the addons.mozilla.org credentials page. You must register if you haven't done so before. From this page you obtain:
user:12345:67
. You supply this to web-ext sign
as the API key in --api-key
.634f34bee43611d2f3c0fd8c06220ac780cff681a578092001183ab62c04e009
. You supply this to web-ext sign
as the API secret in --api-secret
.web-ext sign
You can now run web-ext sign
supplying the API key and location of the JSON file containing the metedata.:
web-ext sign --channel=listed --amo-metadata=<path to your metadata JSON file> --api-key=$AMO_JWT_ISSUER --api-secret=$AMO_JWT_SECRET
If you sign a Manifest V2 extension without an explicit ID, addons.mozilla.org generates an ID and web-ext
saves it to .web-extension-id
in the working directory. Add the ID to the extension's browser_specific_settings.gecko.id
key in its manifest.json file. The ID needs to be present to publish updates with web-ext
.
See the sign reference guide to learn more.
As you improve and update your extension you want to submit new versions for publication on addons.mozilla.org. You can do this using the website or web-ext sign
. To use web-ext sign
you need to:
browser_specific_settings.gecko.id
.When publishing an extension update metadata isn't required. However, any of the properties of the addons.mozilla.org add-on API Version Create request JSON object can be provided.
Visit the addons.mozilla.org credentials page. You must register if you haven't done so before. From this page you obtain:
user:12345:67
. You supply this to web-ext sign
as the API key in --api-key
.634f34bee43611d2f3c0fd8c06220ac780cff681a578092001183ab62c04e009
. You supply this to web-ext sign
as the API secret in --api-secret
.web-ext sign
You can now run web-ext sign
supplying the API key and location of the JSON file containing the metedata.:
web-ext sign --channel=listed --amo-metadata=<path to your metadata JSON file> --api-key=$AMO_JWT_ISSUER --api-secret=$AMO_JWT_SECRET
See the sign reference guide to learn more.
As an alternative to publishing your extension on addons.mozilla.org, you can self-host your package file but it needs to be signed by Mozilla first. The following command packages and signs a ZIP file, then returns it as a signed XPI file for distribution:
web-ext sign --channel=unlisted --api-key=$AMO_JWT_ISSUER --api-secret=$AMO_JWT_SECRET
The API options are required to specify your addons.mozilla.org credentials.
--api-key
: the API key (JWT issuer) from addons.mozilla.org
needed to sign the extension. This is a string that will look something like user:12345:67
.--api-secret
: the API secret (JWT secret) from addons.mozilla.org
needed to sign the extension. This is a string that will look something like 634f34bee43611d2f3c0fd8c06220ac780cff681a578092001183ab62c04e009
.If you've listed the extension on addons.mozilla.org, see Signing a test version of a listed extension.
See the sign reference guide to learn more.
If you're working in an environment that restricts access to certain domains, you can try using a proxy when signing:
web-ext sign --api-key=... --api-secret=... --api-proxy=https://yourproxy:6000
See the --api-proxy option to learn more.
The following domains are used for signing and downloading files:
addons.mozilla.org
addons.cdn.mozilla.net
If you've listed an extension on addons.mozilla.org, use web-ext
to create a signed but unlisted version for testing purposes. For example, you may wish to distribute an alpha or beta version to users for early feedback and testing.
First, change the version number in your manifest.json
so that it is different from the latest listed version. Then, create the unlisted version by using the --channel
option like this:
web-ext sign --channel=unlisted --api-key=... --api-secret=...
This signs and downloads an XPI file that can be installed into Firefox.
See the sign reference guide to learn more.
In this section learn how to:
You can specify --config=my-config.cjs
or --config=my-config.mjs
to set default values for any option. Here is an example with the build
command:
web-ext --config=my-config.mjs build
The file should be a CommonJS module as understood by NodeJS and must export each configuration value. Here is how you would set the default value of --verbose to true
:
export default {
verbose: true,
};
If you want to specify options that only apply to a specific command, you nest the configuration under the command name. Here is an example of adding configuration for --overwrite-dest that only applies to the build
command and --firefox that only applies to the run
command:
export default {
// Global options:
verbose: true,
// Command options:
build: {
overwriteDest: true,
},
run: {
firefox: 'nightly',
},
};
To create a configuration key for a command line option, you remove the preceding dashes and convert the name to camel case. As you can see from this example, --overwrite-dest
was converted to overwriteDest
.
If an option can be specified multiple times on the command line then you define it as an array. For example, here is how to specify multiple --ignore-files patterns:
export default {
ignoreFiles: [
'package-lock.json',
'yarn.lock',
],
};
web-ext
also tries to load its configuration options from a "webExt"
property included in the package.json
file in the current directory:
{
"name": "an-extension-src-dir-with-a-package-json",
"version": "1.0.0",
...
"webExt": {
"sourceDir": "dist/extension/"
}
}
web-ext
loads configuration files in the following order:
.web-ext-config.mjs
in your home directory, for example:
C:\Users\<username>\.web-ext-config.mjs
/Users/<username>/.web-ext-config.mjs
/home/<username>/.web-ext-config.mjs
"webExt"
included in a package.json
file in the current directory.web-ext-config.mjs
in the current directory.(web-ext
also recognizes files named .web-ext-config.cjs
as configuration files.)
If a home directory config and a local directory config define the same option, the value from the latter file is used.
For example, creating ~/.web-ext-config.mjs
containg:
export default {
"sign": {
"apiKey": "<API_KEY>",
"apiSecret": "<API_SECRET>"
}
}
Is the equivalent of:
web-ext sign --api-key <API_KEY> --api-secret <API_SECRET>
To disable automatic loading of configuration files, set this option:
web-ext --no-config-discovery run
To diagnose an issue related to config files, re-run your command with --verbose
. This tells you which config file affected which option value.
In this section learn how to:
The commands use default directories for the extension source and artifact creation (for example, built .zip
files). The defaults are:
./web-ext-artifacts
, created inside the current directory.You can specify different source and destination directories using the --source-dir
and --artifacts-dir
options when running your commands. Their values can be relative or absolute paths, but must always be specified as strings. Here is an example of specifying both options when building an extension:
web-ext build --source-dir=webextension-examples/notify-link-clicks-i18n --artifacts-dir=zips
To see in detail what web-ext is doing when you run a command, include the --verbose option. For example:
web-ext build --verbose
You can list all commands and options like this:
web-ext --help
You can list options for a specific command by adding it as an argument:
web-ext --help run
Your extension can detect whether it was installed using web-ext run
, rather than as a built and signed extension downloaded from addons.mozilla.org
. Listen for the runtime.onInstalled
event and check the value of details.temporary
.
You can use web-ext
as a NodeJS module
. Here is more information, with example code.
Develop
Develop
Develop