Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Build Browser Extension

ASecurity

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.

7 stars
0 votes
0 copies
0 views
Added 9/23/2026
ai-agentsrustapifrontend

Works with

cliapi

Security Analysis

A100/100

Scanned 9/23/2026

$npx -y skills add mcorbett51090/RavenClaude --skill build-browser-extension --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Build Browser Extension?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Build Browser Extension
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mcorbett51090-build-browser-extension/badge)](https://www.skillsdirectory.com/skills/mcorbett51090-build-browser-extension)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: build-browser-extension
description: "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`](../../knowledge/where-logic-lives.md) and
[`../../knowledge/manifest-v3-architecture.md`](../../knowledge/manifest-v3-architecture.md)
**before** placing logic or requesting a permission.

## 1. Architecture — where does each piece of logic live?

Pick the **least-privileged context that works** (full tree:
[`../../knowledge/where-logic-lives.md`](../../knowledge/where-logic-lives.md)):

| Need | Context |
|---|---|
| Read/modify a page's **DOM** (not its JS) | **Content script** (isolated world) |
| Reach the page's **own JS / window globals** | **Injected page script** (main world) — untrusted, bridge via `postMessage` |
| Privileged `chrome.*` APIs (tabs, alarms, network), background work | **Service worker** (MV3 background) — ephemeral, no DOM |
| Toolbar UI | **Popup** (`action.default_popup`) — transient |
| Settings / full page | **Options / extension page** |

**Never assume two contexts share memory.** Cross-context state lives in
`chrome.storage` or is passed by message.

## 2. Service worker discipline

MV3's background is **event-driven and terminated when idle** — re-think any
"long-running/stateful" design:

- Register **all** event listeners at the **top level**, synchronously, on every
  load — not inside an async callback, or the wake-up event is missed.
- Hold **no** in-memory state you can't lose; persist to `chrome.storage`,
  re-hydrate on wake.
- No DOM, no `localStorage` — it's a worker. (See
  [`../../best-practices/treat-the-background-as-ephemeral.md`](../../best-practices/treat-the-background-as-ephemeral.md).)

## 3. Messaging

- Content script ↔ service worker ↔ popup/options → `chrome.runtime.sendMessage`
  / `onMessage`, or a long-lived `chrome.runtime.connect` `Port`; 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).

See [`../../best-practices/message-pass-across-the-isolation-boundary.md`](../../best-practices/message-pass-across-the-isolation-boundary.md).

## 4. Least-privilege permissions

Walk the permissions tree narrowest-first — escalate only when a concrete feature
forces it, and justify each escalation in the listing:

1. **`activeTab`** — temporary current-tab access on a user gesture; no install
   warning. The default for user-initiated, current-tab actions.
2. **Specific API perms** — exactly the `chrome.*` APIs you use (`storage`,
   `alarms`, `scripting`).
3. **Narrow `host_permissions`** — specific match patterns
   (`https://api.example.com/*`), never `<all_urls>` reflexively.
4. **`optional_permissions` / `optional_host_permissions`** — request broad access
   at runtime with `chrome.permissions.request()` on a user action.
5. **`<all_urls>`** — only when running on arbitrary sites *is* the core function;
   expect stricter review.

Re-audit at every release; drop unused permissions. Run the deeper audit with
[`../manifest-permissions-audit/SKILL.md`](../manifest-permissions-audit/SKILL.md)
(and see [`../../best-practices/request-least-privilege-permissions.md`](../../best-practices/request-least-privilege-permissions.md)).

## 5. Store submission checklist

- [ ] `manifest_version: 3`, version bumped.
- [ ] **No remotely-hosted code** — all executable JS ships in the package (fetch
      data, not code). (See
      [`../../best-practices/no-remotely-hosted-code.md`](../../best-practices/no-remotely-hosted-code.md).)
- [ ] Permissions minimized and **re-audited**; each (and any broad host access)
      justified.
- [ ] `web_accessible_resources` scoped to specific files + origins, never `*`.
      (See [`../../best-practices/scope-web-accessible-resources.md`](../../best-practices/scope-web-accessible-resources.md).)
- [ ] Privacy policy + accurate data-use disclosures.
- [ ] 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.

Run the full per-store readiness pass with
[`../store-submission-readiness/SKILL.md`](../store-submission-readiness/SKILL.md);
the cross-browser delta + the three pipelines live in
[`../../knowledge/cross-browser-and-stores.md`](../../knowledge/cross-browser-and-stores.md).

## Seam — the UI is a frontend app

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`](../../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`](../../knowledge/where-logic-lives.md)
(where logic lives) and
[`../../knowledge/manifest-v3-architecture.md`](../../knowledge/manifest-v3-architecture.md)
(permissions-minimization). MV3 specifics are volatile — verify at use against the
Chrome/MDN/Firefox docs.

Attribution

mcorbett51090mcorbett51090
View sourceSee grades on GitHubMore from mcorbett51090 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698461 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →