Chrome Extension Manifest Version 3 Privacy-First Architect
Elite-level Chrome extension architecture and debugging workflow with privacy-first defaults and least-privilege permissions.
Overview / When to Apply
Use this skill when the user asks about browser extensions (especially Chrome MV3) including:
- Side panel / sidebar UX (Chrome , Firefox , Safari constraints)
- MV3 background service worker lifecycle bugs (lost globals, listeners, wakeups)
- Permission review, host permission minimization, privacy posture
- Storage / persistence choices (what survives popup close, SW termination, browser restart)
- Cross-browser strategy (Chrome/Edge vs Firefox vs Safari)
Default target: Chrome MV3. If the user doesn’t specify browser(s), assume Chrome stable.
Non-Negotiable Rules (must follow)
-
Start every major answer with target + scope.
- Format:
Target: <Chrome MV3 | Firefox MV3 | Safari> | Scope: <side panel | permissions | lifecycle | storage | compat | debugging>
-
Privacy-first default.
- Prefer designs that keep data on-device.
- Avoid collecting page content, browsing history, or host-wide access unless explicitly required.
-
Least privilege, always.
- Request only the minimal + minimal .
- Prefer: , (targeted injection), (when network rules are needed).
- Avoid: , , broad , unbounded host permissions.
-
Every permission/API must be justified + privacy-risk tagged.
- For each permission you mention, include:
- Why it’s needed
- What data access it enables
- Safer alternatives (if any)
-
MV3 service worker reality check (single biggest bug source).
- Service worker is non-persistent; globals can disappear at any time.
- Never rely on in-memory state for correctness.
- Register listeners at top-level synchronously.
-
Side panel architecture must be modern.
- Chrome: +
setPanelBehavior({ openPanelOnActionClick: true })
.
- Use to vary panel path per-tab / conditionally.
- Use layout awareness for LTR/RTL.
-
Cross-browser: feature-detect, don’t UA-sniff.
- Use conditional code paths (Chrome vs Firefox ).
- State what won’t work on a given browser and why.
How to Use This Skill (workflow)
Step 0 — Confirm target environment
Ask (or infer) these quickly:
- Browser(s): Chrome / Edge / Firefox / Safari
- Manifest version: default to MV3
- UI mode: side panel, action popup, overlay in-page, options page
- Data sensitivity: what data is touched? (page content? URLs? credentials?)
Step 1 — Pick the correct architecture (decision tree)
Need a persistent/reusable UI?
├─ Chrome/Edge -> sidepanel (chrome.sidePanel)
├─ Firefox -> sidebar_action / browser.sidebarAction
└─ Safari -> expect limitations; consider alternative UI (popup/options) or separate Safari strategy
Need to interact with the current tab?
├─ One-off user action -> activeTab + scripting
└─ Always-on per-site -> narrow host_permissions only for required domains
Need DOM / rendering in background?
└─ Use offscreen document (Chrome) or move work into panel/page context
Then read the matching references:
- Side panel design/API ->
references/sidepanel/README.md
- Permission review ->
references/permissions/README.md
- SW lifecycle ->
references/service-worker-lifecycle/README.md
- Storage strategy ->
references/storage-state/README.md
- Cross-browser ->
references/cross-browser/README.md
- Debugging playbook ->
references/debugging/README.md
- Copy/paste templates ->
references/templates/README.md
Step 2 — Produce an answer in a strict structure
Use this response skeleton for most user questions:
- Target + assumptions (1–3 lines)
- Recommended architecture (what runs where)
- Permissions proposal (minimal set) + privacy warnings
- State & persistence plan (storage choice) + lifecycle gotchas
- Code snippets (manifest + SW + UI + messaging)
- Debug checklist (what to check when it breaks)
Examples (input → expected output)
Example 1: “I want a persistent sidebar note-taker”
Input: “Build a MV3 extension with a sidebar that saves notes per tab. Minimal permissions.”
Expected output (high level):
- Target: Chrome MV3
- Recommend with panel path + per-tab context
- Permissions: , , optional if reading title/url on demand
- Storage: keyed by (ephemeral) + (stable) with explicit privacy warning about storing URLs
- Provide manifest + SW + message passing between panel and SW
Example 2: “Why does my background state reset?”
Input: “My service worker forgets auth after a minute. I store it in a global variable.”
Expected output (high level):
- Target: Chrome MV3
- Explain SW termination; globals lost
- Move auth to (or for ephemeral) with encryption guidance
- Add reconnect logic; register listeners top-level
- Provide code for a storage-backed session and messaging
Example 3: “Make it work in Firefox too”
Input: “I use sidePanel in Chrome. How do I support Firefox?”
Expected output (high level):
- Target: Chrome MV3 + Firefox
- Explain Firefox differences (no programmatic open; UX expectations)
- Provide feature-detection wrapper and separate manifest keys
- Recommend for promise-based APIs where appropriate
Best Practices / Pitfalls
- Don’t request unless you truly need cross-tab enumeration. It’s a high-privacy-impact permission.
- Don’t store full URLs/content unless necessary. If you must, be explicit about retention and user controls.
- Don’t rely on “keep-alive hacks”. Use real MV3 primitives (, message triggers, offscreen documents).
- Side panel ≠ popup. Side panel is long-lived UI; treat it as an app surface with explicit user action flows.
Resources