Firefox WebExtensions API: What Makes a Browser Extension Tick
Every Firefox extension is built on the WebExtensions API — a standard that also powers Chrome and Edge extensions. Here is a plain-language explanation of how it works.
What a Firefox extension is
A Firefox extension is a zip file (renamed .xpi) containing:
-
manifest.json— the extension's metadata and permissions list - JavaScript files — the logic
- HTML/CSS files — any popup or settings UI
- Images — icons
Firefox reads the manifest, registers the extension's permissions, and loads the JavaScript.
The three parts of an extension
Background script: JavaScript that runs continuously or on-demand, invisible to the user. This is where event listeners live (tab changes, browser startup, etc.). New extensions use "service workers" (Manifest V3) instead of persistent background pages.
Content scripts: JavaScript injected into web pages. This is how extensions like NightOwl inject CSS to change how sites look, or how grammar checkers read the text you have selected.
Popup: The HTML page that appears when you click the extension icon. This is what you see when you open Tab Manager or Voice Notes.
How permissions work
The manifest.json lists the APIs the extension needs access to. Common permissions:
-
storage: Save settings or data to Firefox's local storage -
tabs: Read and modify tab information -
activeTab: Access the current tab (less powerful thantabs) -
<all_urls>: Run content scripts on all websites
Mozilla's AMO review process checks whether each permission is justified by the extension's function. Extensions requesting excessive permissions may be rejected.
The browser.storage API
Extensions use browser.storage.local to persist data. This is a simple key-value store:
// Save browser.storage.local.set({ 'tasks': ['Buy milk', 'Send email'] }); // Retrieve browser.storage.local.get('tasks').then(data => { console.log(data.tasks); // ['Buy milk', 'Send email'] }); This is how Daily Planner stores your tasks, Habit Tracker stores your grid, and Tab Manager stores your sessions — all without a backend.
Why I built on this API
The WebExtensions API is cross-browser by design. Extensions written for Firefox also run on Chrome and Edge with minor modifications. The API is well-documented on MDN and has been stable for years.
For the 11 extensions in this series, the local storage model and the popup/content script architecture were the right fit: simple, no backend needed, standard API, reviewable code.
These are 11 Firefox extensions I built — see the full series.