Configuration files (config.js)
config.js is the entry point of the whole system. It is the only file Firefox itself has to
notice. Everything else is loaded from it. Its job is to start the chain: enable Firefox's
AutoConfig mechanism, lock the two preferences that let legacy add-ons load, register the utils'
chrome.manifest, and then load BootstrapLoader.js and userChrome.js in order.
In plain language
Section titled “In plain language”Firefox has a switch that lets an administrator run a startup script, normally used by IT departments. These two small files flip that switch so Firefox loads the helper scripts every time it starts. You never edit them: the installer puts them in Firefox's own folder, and they sit there quietly. The one thing worth knowing is that a Firefox update (and on macOS, every update) can wipe that folder. If your add-ons suddenly stop loading after an update, reinstalling the configuration files is the first fix to try. How it works under the hood follows below.
Firefox's AutoConfig
Section titled “Firefox's AutoConfig”Firefox has a built-in mechanism for administrators to run their own JavaScript at startup,
before the browser window exists: AutoConfig.
It is the same mechanism behind mozilla.cfg on managed installs, and it does two things:
- sets (or locks) preferences, with
pref()/lockPref(); - runs the rest of the file as script, so it can register components or load more files.
AutoConfig is off by default. Turning it on takes two files, both placed in the browser's installation directory:
| File | Purpose |
|---|---|
defaults/pref/config-prefs.js |
the preferences that enable AutoConfig and point it at our file |
config.js |
the script AutoConfig runs |
The three preferences
Section titled “The three preferences”This is the whole of defaults/pref/config-prefs.js:
pref("general.config.obscure_value", 0);pref("general.config.filename", "config.js");pref("general.config.sandbox_enabled", false);general.config.filename: the name of the script AutoConfig runs, relative to the browser installation directory. Firefox's default ismozilla.cfg; ours isconfig.js.general.config.sandbox_enabled: whentrue(the default), the AutoConfig script runs in a restricted sandbox limited to a documented API, enough forpref(), and nothing more. These scripts needServices,Componentsand chrome-privileged APIs, so the sandbox is disabled.general.config.obscure_value: whentrue, the values of the preferences AutoConfig sets are hidden inabout:config. Set to0so the two locked preferences below are visible and can be verified.
What config.js does
Section titled “What config.js does”Locked first, so no preference or about:config edit can undo them:
lockPref("xpinstall.signatures.required", false);lockPref("extensions.install_origins.enabled", false);xpinstall.signatures.required: legacy add-ons are not signed. With signature enforcement on, they are refused as corrupt.extensions.install_origins.enabled: legacy extensions install from any origin rather than being pinned to the add-on site's host.
Then the loading itself:
const cmanifest = Services.dirsvc.get("UChrm", Ci.nsIFile);cmanifest.append("utils");cmanifest.append("chrome.manifest");Components.manager .QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(cmanifest);
if (!isWaterfox) { Services.scriptloader.loadSubScript( "chrome://userchromejs/content/BootstrapLoader.js", );}
Services.scriptloader.loadSubScript( "chrome://userchromejs/content/userChrome.js",);Three steps, all inside try/catch so a failure in one cannot stop the browser from starting:
- Register the utils'
chrome.manifest. It mapschrome://userchromejs/to theutilsfolder andchrome://firefox-scripts/toupdater/, so the other scripts can be loaded bychrome://URL.UChrmis the profile'schromedirectory. This is why the utils must be unpacked tochrome/utils/, not anywhere else. - Load
BootstrapLoader.js: brings legacy add-ons back, unless the browser already ships its own loader (see below). - Load
userChrome.js: the.uc.jsloader, and the in-browser updater's UI hook.
Waterfox: skipping the loader
Section titled “Waterfox: skipping the loader”const isWaterfox = /waterfox/i.test(Services.appinfo.name);Waterfox bundles its own Bootstrap Loader. Loading ours as well would register a second
bootstrap loader and double-patch the about:addons internals, which breaks legacy add-ons. So
on Waterfox the BootstrapLoader.js load is skipped. userChrome.js and the updater still load,
because those are what a user installing these files on Waterfox actually wants.
BootstrapLoader.js carries the same guard internally, so it also stays inert if something else
loads it (a custom config.js that ignores the check, or a user script re-evaluating the file).
Verifying it worked
Section titled “Verifying it worked”about:config→ searchxpinstall.signatures.required: it must be present and locked (shown in bold with a lock icon).about:support→ Application Basics: the Profile Folder line tells you where thechromedirectory must live.about:support→ Extensions lists the loaded legacy add-on.
If the preferences are not locked, the file is not being read. See Troubleshooting.