End-to-end workflow to build a Manifest V3 browser extension: decide which context owns each piece of logic (content script vs MV3 service worker vs injected page script vs popup/options), wire messaging between contexts, request the narrowest permissions (activeTab -> optional -> host -> all_urls), and pass Chrome/Edge/Firefox store review. Complements the manifest-permissions-audit and store-submission-readiness skills. The popup/options UI seams to frontend-engineering.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
End-to-end workflow to build a Manifest V3 browser extension: decide which context owns each piece of logic (content script vs MV3 service worker vs injected page script vs popup/options), wire messaging between contexts, request the narrowest permissions (activeTab -> optional -> host -> all_urls), and pass Chrome/Edge/Firefox store review. Complements the manifest-permissions-audit and store-submission-readiness skills. The popup/options UI seams to frontend-engineering.
Skill: Build a Browser Extension (Manifest V3)
A browser extension is a multi-context distributed system: its UI is a frontend
app, but its execution model (ephemeral service worker, isolated content scripts,
a strict permission/store regime) is what makes it distinctive. This skill is the
end-to-end build workflow; pair it with the deeper audit/checklist skills it
references at each step. Traverse the decision trees in
../../knowledge/where-logic-lives.md and
../../knowledge/manifest-v3-architecture.mdbefore placing logic or requesting a permission.
1. Architecture — where does each piece of logic live?
Content script ↔ service worker ↔ popup/options → chrome.runtime.sendMessage
/ onMessage, or a long-lived chrome.runtime.connectPort; service worker →
a tab → chrome.tabs.sendMessage.
Content script (isolated) ↔ injected page script (main world) →
window.postMessage is the only bridge — validate origin, source, and
message shape; treat it as untrusted input.
Return true from an onMessage listener that responds asynchronously, and
remember the worker may have been asleep (don't rely on prior in-memory state).
Icons, screenshots, listing copy; single-purpose description that matches
behavior.
Tested on each target: Chrome, Edge (Chromium — usually drop-in),
Firefox (browser.*/Promise differences, webextension-polyfill,
browser_specific_settings.gecko.id, every version signed).
declarativeNetRequest rules (if any) validated; content-script match
patterns as narrow as the feature allows.
After publish: staged/percentage rollout where supported; monitor reviews +
error telemetry.
The popup / options UI is an ordinary frontend and routes to
frontend-engineering, not this skill: components/forms/accessibility, client
state (note chrome.storage + onChanged is the persistence/sync layer — don't
bolt a global store onto an already-transient popup), and popup open-speed/bundle
discipline (a popup must open fast, so bundle discipline matters more, not
less). See ../../CLAUDE.md §1 and §3.
This skill owns only the MV3-distinctive layer (context placement, service-worker
lifetime, messaging, permissions, store review). Full reference + the two Mermaid
decision trees:
../../knowledge/where-logic-lives.md
(where logic lives) and
../../knowledge/manifest-v3-architecture.md
(permissions-minimization). MV3 specifics are volatile — verify at use against the
Chrome/MDN/Firefox docs.