Firefox extension Manifest V3 starter: popup, background, and gecko settings
A minimal MV3 Firefox WebExtension layout with manifest.json, service worker, popup, and browser_specific_settings.gecko before Stripe checkout or Payhook Pro gating.
#manifest-v3#firefox#webextensions#getting-started
This tutorial walks through a minimal Manifest V3 add-on for Firefox. Payhook tutorials assume you have this skeleton before wiring payments. The same files often load in Chrome after small tweaks - see Chrome extension Manifest V3 starter for the Chrome-only view.
What you will build
manifest.jsonwith MV3 fields and gecko metadata- A service worker (
background.js) for long-lived logic - A popup (
popup.html+popup.js) for user-facing controls
manifest.json
{
"manifest_version": 3,
"name": "My Firefox Add-on",
"version": "0.1.0",
"description": "Starter MV3 WebExtension for Firefox",
"browser_specific_settings": {
"gecko": {
"id": "my-addon@example.com",
"strict_min_version": "109.0"
}
},
"action": {
"default_popup": "popup.html",
"default_title": "My Add-on"
},
"background": {
"service_worker": "background.js"
},
"permissions": ["storage"]
}
Replace my-addon@example.com with a unique ID you control before publishing to Firefox Add-ons (AMO).
Load temporarily in Firefox
- Open
about:debugging - Click This Firefox
- Load Temporary Add-on… → select
manifest.json
Temporary loads clear when Firefox restarts. Use AMO for persistent installs - Publish a Firefox extension to AMO.
Popup vs background
| Surface | Use for |
|---|---|
| Popup | Buttons, upgrade CTA, quick settings |
| Service worker | Entitlement checks, messaging, alarms |
Use the browser.* namespace in scripts (Firefox’s WebExtensions API). For cross-browser code, add webextension-polyfill or prompt your AI to generate compatible calls.
Firefox vs Chrome checklist
| Item | Firefox | Chrome |
|---|---|---|
| Gecko ID | Required in manifest | Not used |
| Load unpublished | about:debugging | chrome://extensions |
| Storage API | browser.storage | chrome.storage |
| Store | AMO | Chrome Web Store |
Example popup script
document.getElementById('status').textContent = 'Add-on loaded';
document.getElementById('save').addEventListener('click', async () => {
await browser.storage.sync.set({ enabled: true });
});
Next steps
- Create your first Firefox extension with Claude Code - build Focus Tab with an AI agent
- Stripe Connect for extension builders - products and checkout concepts
- Monetize a browser extension without a payment backend - hosted checkout (works in Firefox too)
Related: Payhook docs, acme-extension sample.