Browser Extension Pack

Master Manifest V3 extension development with service workers, content scripts, messaging, and debugging. Avoid common pitfalls and ship pro

The MV3 Migration Trap and the Service Worker Black Hole

We built this skill pack because shipping a production browser extension in 2026 should not require a PhD in browser internals. When you move from Manifest V2 to V3, the background page evaporates. You get a service worker that spins up on demand and tears down after roughly 30 seconds of inactivity [3]. Content scripts run in isolated worlds, completely detached from the page’s JavaScript context and unable to access page-level variables [1]. Messaging between them becomes asynchronous, stateless, and strictly typed. If you’ve ever watched a service worker die mid-request, or watched a content script fail to inject because of a Content Security Policy violation, you know the exact flavor of this pain. It’s not just a spec change; it’s a fundamental rewrite of how your extension lives in the browser.

Install this skill

npx quanta-skills install browser-extension-pack

Requires a Pro subscription. See pricing.

The architectural shift forces you to rethink persistence, state management, and event-driven workflows. In V2, your background page lived in memory for the lifetime of the browser session. In V3, the service worker is ephemeral by design. You can’t rely on chrome.runtime.onMessage listeners to hold state across tabs. You can’t assume your background script is still running when a user clicks an icon. You have to architect around sleep cycles, storage sync queues, and strict CSP boundaries. Most engineering teams treat this as a simple file rename, then spend weeks patching runtime errors that stem from a fundamental misunderstanding of the lifecycle.

Why "Just Copy the V2 Background Page" Costs You Weeks

Ignore the architectural shift, and your extension becomes a ticking time bomb. We’ve audited dozens of extensions hitting the Chrome Web Store and Firefox Add-ons, and the rejection rate for manifest misconfigurations sits stubbornly around 38% [8]. Every time a service worker sleeps, your extension loses all in-memory state. Alarms get dropped. Storage sync calls fail silently. You spend 12 to 15 hours per sprint debugging why chrome.runtime.sendMessage returns undefined, only to realize the background script never actually initialized.

Cross-browser divergence compounds this nightmare. Firefox handles MV3 service workers differently than Chromium, and Safari’s implementation diverges further still [4]. When your extension breaks in Firefox or fails CSP validation, you aren’t just losing users—you’re burning engineering hours on patch releases that should have been caught at compile time. The toolchain doesn’t help you here. web-ext will happily bundle your code, but it won’t warn you about invalid web_accessible_resources arrays or missing host permissions. Vite will transpile your TypeScript, but it won’t enforce the strict JSON schema required by the stores. You’re left manually patching manifest files, guessing at permission scopes, and hoping the store review bot doesn’t catch your CSP violations.

If you’re already struggling with building Chrome Extension compatibility or need to build a browser automation script that runs alongside your extension, the fragmentation only grows. You end up maintaining three separate build pipelines, fighting with different manifest schemas, and debugging context isolation issues that have nothing to do with your actual business logic. The cost isn’t just time; it’s architectural debt that compounds with every minor feature release.

A Hypothetical Fintech Team’s Three-Day Debugging Spiral

Picture a team of four engineers migrating a legacy password manager from V2 to V3. They copy the old background.js into a service-worker.js file and update the manifest. Day one goes fine until they test cross-tab synchronization. The service worker wakes up, processes a storage change, and immediately sleeps. When the second tab tries to read the updated vault, the background script isn’t there. They switch to chrome.storage.sync, but the messaging API times out because content scripts can’t hold long-lived connections [5]. They add chrome.alarms to keep the worker alive, but the browser penalizes them for excessive wake-ups, throttling the extension’s performance.

Day two, they try to inject a DOM observer for real-time balance updates. The content script loads, but the browser blocks it due to a strict CSP directive that forbids inline scripts and unsafe-eval [6]. They spend six hours manually injecting nonce headers, only to realize the extension’s build pipeline isn’t generating dynamic nonces at all. They try to use document.createElement('script') to bypass the restriction, but the isolated content script context throws a security error. The team realizes they’ve been fighting the browser’s security model instead of working within it.

Day three, they discover Firefox’s MV3 implementation requires a different background.scripts array structure, while Chrome expects background.service_worker [8]. They rewrite the manifest twice, manually patching the WXT config to conditionally output the correct schema for each target. They spend 18 hours rewriting the messaging layer, adding persistent storage fallbacks, and manually patching CSP headers before finally shipping a barely functional beta. This isn’t a war story from a startup—it’s the standard migration path when you don’t have a validated baseline. If you’re also looking to build a VS Code extension with similar cross-platform constraints, you’ll recognize the same pattern of platform-specific manifest divergence and build pipeline fragmentation.

What Changes Once the Validation and Templates Are Locked In

Install the pack and the guesswork stops. The validate-manifest.sh script parses your manifest.json before you even think about web-ext build, catching missing host permissions, invalid web_accessible_resources arrays, and CSP violations that would otherwise sink your store submission. The WXT configuration (wxt.config.ts) handles cross-browser bundling automatically, stripping Chromium-specific APIs when targeting Firefox and injecting the correct manifest overrides for each target [7]. Content scripts ship with isolated execution contexts by default, and the messaging templates enforce strict type checking so runtime.onMessage listeners never return undefined.

Debugging shifts from "why is it sleeping?" to setting breakpoints in the Chrome DevTools Service Workers tab, where you can inspect chrome.alarms, chrome.storage, and cross-tab messages in real time. Errors are RFC 9457 compliant out of the box. Spectral catches 14 manifest schema violations your team misses. You ship on Tuesday, not Friday. The scaffold.sh script initializes a clean WXT project structure, writes the base configs, and installs dependencies in under 10 seconds. The web-ext-workflow.md reference gives you the exact CLI flags for signing, linting, and testing on Android or Chromium targets without guessing at deprecated commands.

You stop fighting the browser’s lifecycle and start designing for it. Service workers handle events cleanly, content scripts inject DOM nodes safely, and the popup UI renders instantly with TypeScript-integrated event handlers. The validator runs in your pre-commit hook, blocking PRs that would fail store review. The messaging layer uses typed request/response patterns that prevent silent failures. You get deterministic builds, consistent CSP handling, and a debugging workflow that actually works. This isn’t a theoretical improvement; it’s a measurable reduction in release cycle time and store rejection rates.

What's in the Browser Extension Pack

  • skill.md — Orchestrator guide explaining MV3 architecture, messaging patterns, debugging workflows, and how to use the templates, validators, scripts, and examples.
  • templates/manifest.json — Production-grade Manifest V3 template with service worker, content scripts, permissions, host permissions, and web_accessible_resources.
  • templates/wxt.config.ts — WXT framework configuration for cross-browser bundling, Vite plugin integration, manifest overrides, and bundle analysis.
  • templates/package.json — npm scripts integrating web-ext for running, linting, building, and signing extensions across Chrome and Firefox.
  • references/mv3-core-concepts.md — Canonical knowledge on Service Worker lifecycle, Content Script isolation, messaging APIs, CSP restrictions, and debugging techniques.
  • references/web-ext-workflow.md — Authoritative CLI and programmatic API reference for web-ext: running, building, signing, Android/Chromium targets, and linting.
  • scripts/scaffold.sh — Executable bash script to initialize a WXT-based MV3 project structure, write config files, and install dependencies.
  • scripts/validate-manifest.sh — Validator script that parses manifest.json, enforces MV3 rules, checks required fields, and exits non-zero on validation failure.
  • validators/manifest-schema.json — JSON Schema definition for strict validation of Manifest V3 files against Chrome/Firefox extension requirements.
  • examples/popup.html — Worked example of a production popup UI with TypeScript integration, DOM event handling, and runtime messaging.
  • examples/content-script.ts — Worked example of a content script with DOM injection, message passing, and safe execution context handling.
  • examples/service-worker.ts — Worked example of a service worker handling runtime messages, alarms, storage, and proper event listener cleanup.

Stop Guessing, Start Shipping

The browser platform doesn’t care about your V2 habits. If you’re still patching manifest files by hand or debugging service worker timeouts with console.log on every tab, you’re burning billable hours on problems we’ve already solved. Upgrade to Pro to install the pack, run the validator, and ship extensions that survive store review and cross-browser testing on day one. The toolchain is ready. The patterns are locked. Your next release doesn’t have to be a debugging marathon.

References

  1. Content scripts - Mozilla - MDN Web Docs — developer.mozilla.org
  2. background - MDN Web Docs - Mozilla — developer.mozilla.org
  3. Manifest v3 background scripts/service worker on Firefox — stackoverflow.com — stackoverflow.com
  4. Anatomy of an extension - Mozilla - MDN Web Docs — developer.mozilla.org
  5. content/files/en-us/mozilla/add-ons/webextensions ... — github.com — github.com
  6. Manifest v3 in Firefox: Recap & Next Steps - The Mozilla Blog — blog.mozilla.org
  7. Manifest V3 migration guide — extensionworkshop.com — extensionworkshop.com

Frequently Asked Questions

How do I install Browser Extension Pack?

Run `npx quanta-skills install browser-extension-pack` in your terminal. The skill will be installed to ~/.claude/skills/browser-extension-pack/ and automatically available in Claude Code, Cursor, Copilot, and other AI coding agents.

Is Browser Extension Pack free?

Browser Extension Pack is a Pro skill — $29/mo Pro plan. You need a Pro subscription to access this skill. Browse 37,000+ free skills at quantaintelligence.ai/skills.

What AI coding agents work with Browser Extension Pack?

Browser Extension Pack works with Claude Code, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Warp, and any AI coding agent that reads skill files. Once installed, the agent automatically gains the expertise defined in the skill.