Create your first Firefox extension with Claude Code (step-by-step tutorial)
Build a Manifest V3 Firefox add-on from a plain-English prompt in Claude Code, load it via about:debugging, fix gecko compatibility, and prepare Pro monetization with Stripe and Payhook.
#claude-code#firefox#manifest-v3#webextensions#tutorial
Firefox add-ons use the same WebExtensions model as Chrome, but loading, IDs, and a few APIs differ. Claude Code handles those details when you prompt clearly - this tutorial walks through building Focus Tab (a timed site blocker) for Firefox, then points you at Payhook when you are ready to sell Pro.
If you prefer a no-code brief, start with Create a Firefox extension without coding.
What you will build
Focus Tab for Firefox - a Manifest V3 add-on that:
- Shows a popup with a 25-minute focus timer and start/stop controls
- Blocks configured distracting domains while a session is active
- Persists settings in
browser.storage.sync(Firefox’s WebExtensions namespace) - Includes
browser_specific_settings.geckoso AMO and temporary loads accept the add-on
No payment code in this post. Monetization comes in Monetize a browser extension without a payment backend - the same Payhook flow works in Firefox.
Prerequisites
| Requirement | Notes |
|---|---|
| Claude Code | Terminal CLI (claude --version) |
| Firefox | For about:debugging temporary loads |
| Empty project folder | e.g. ~/projects/focus-tab-firefox |
| Claude account | Pro, Max, Team, or Enterprise for Claude Code |
Step 1 - Create a project folder
mkdir -p ~/projects/focus-tab-firefox
cd ~/projects/focus-tab-firefox
Step 2 - Add context with CLAUDE.md
# Focus Tab - Firefox MV3 WebExtension
- manifest_version: 3 only
- Use browser.storage.sync (or webextension-polyfill with browser namespace)
- Service worker: background.js
- Popup: popup.html + popup.js
- Include browser_specific_settings.gecko with a unique id (email-style)
- Target Firefox 109+; keep permissions minimal
- After changes, remind me to reload via about:debugging
Ask Claude Code: “Add a CLAUDE.md for a Firefox Manifest V3 WebExtension project.”
Step 3 - Start Claude Code and send the build prompt
claude
Paste this prompt:
Create a Firefox WebExtension (Manifest V3) called "Focus Tab" in this folder.
Requirements:
1. manifest.json with manifest_version 3, browser_specific_settings.gecko id "focus-tab@example.com", action default_popup popup.html, background service_worker background.js, permissions: storage, declarativeNetRequest (host_permissions only if needed)
2. popup.html + popup.js: 25-minute focus timer UI, Start and Stop buttons, show remaining time
3. background.js: when a focus session is active, block twitter.com, x.com, facebook.com, instagram.com, reddit.com using declarativeNetRequest or equivalent MV3 approach
4. browser.storage.sync: save block list and session state
5. Use the browser.* API namespace (not chrome.*) or include webextension-polyfill
6. icons: placeholder PNGs in icons/ (16, 48, 128)
7. README.md with steps to load via about:debugging → This Firefox → Load Temporary Add-on
Plain JavaScript, no bundler. Must load immediately in Firefox.
Useful follow-up prompts
- “Fix manifest errors from about:debugging when loading temporary add-on.”
- “Add gecko strict_min_version and data_collection_permissions if Firefox warns about them.”
- “Make this codebase also load in Chrome with the smallest diff.”
Step 4 - Review the file structure
focus-tab-firefox/
├── CLAUDE.md
├── README.md
├── manifest.json
├── background.js
├── popup.html
├── popup.js
├── icons/
└── (optional) rules.json
Confirm in manifest.json:
"manifest_version": 3"browser_specific_settings": { "gecko": { "id": "focus-tab@example.com", ... } }"background": { "service_worker": "background.js" }
Change the gecko id to something you own before publishing to AMO.
Step 5 - Load the add-on in Firefox
- Open Firefox and go to
about:debugging - Click This Firefox in the sidebar
- Click Load Temporary Add-on…
- Select
manifest.jsonin your project folder
If Firefox shows errors, paste them into Claude Code:
Firefox reports this error when loading temporary add-on: [paste error]. Fix the project.
After code changes, click Reload on the add-on card in about:debugging.
Temporary add-ons disappear when Firefox restarts. That is expected until you publish to AMO.
Step 6 - Test in the browser
| Check | How |
|---|---|
| Popup opens | Click the toolbar icon |
| Timer runs | Start a session; countdown updates |
| Blocking works | Visit a blocked site during an active session |
| State survives reload | Restart Firefox - settings should persist via storage |
Firefox-specific issues
Missing gecko ID - Firefox requires browser_specific_settings.gecko.id for signing and updates. Use a unique email-style string you control.
chrome.* vs browser.* - Firefox supports many chrome.* aliases, but prefer browser.* or webextension-polyfill for cross-browser code.
Service worker sleep - Long timers may need browser.alarms instead of setInterval. Prompt: “Move the focus timer to browser.alarms so it survives service worker sleep in Firefox.”
DeclarativeNetRequest - Supported in recent Firefox; if rules fail, ask Claude to verify declarative_net_request permission and static rules file format.
Ship to AMO (when ready)
See Publish a Firefox extension to AMO for zipping, developer account setup, and review tips.
Monetize next (Stripe + Payhook)
When Focus Tab should have a Pro tier:
- Connect Stripe in dashboard.payhook.link
- Read Stripe Connect for extension builders
- Add unlock flow with Monetize a browser extension without a payment backend
Copy into Claude Code:
Integrate Payhook into this Firefox WebExtension as the premium unlock flow.
Requirements:
- Add the Payhook UpgradeButton in the popup for paid tiers
- Gate Pro features with Payhook entitlement checks (no custom license server)
- Open hosted Stripe checkout via unlock.payhook.link - do not build a custom Stripe backend
- Use browser.* APIs compatible with Firefox
Payhook: https://dashboard.payhook.link
MCP: https://mcp.payhook.link
Next steps
- Firefox extension Manifest V3 starter - manual skeleton
- Create a Firefox extension without coding
- Create your first Chrome extension with Claude Code - same project, different browser
- Sample extension on GitHub