chrome-extension-architect

Privacy-first Chrome Manifest Version 3 extension architect - sidePanel design, MV3 service worker lifecycle, least-privilege permission audits, storage strategy, cross-browser sidebar patterns, and headless Playwright testing.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "chrome-extension-architect" with this command: npx skills add alcyone-labs/agent-skills/alcyone-labs-agent-skills-chrome-extension-architect

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 chrome.sidePanel, Firefox sidebar_action, 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)

  1. Start every major answer with target + scope.

    • Format: Target: <Chrome MV3 | Firefox MV3 | Safari> | Scope: <side panel | permissions | lifecycle | storage | compat | debugging>
  2. Privacy-first default.

    • Prefer designs that keep data on-device.
    • Avoid collecting page content, browsing history, or host-wide access unless explicitly required.
  3. Least privilege, always.

    • Request only the minimal permissions + minimal host_permissions.
    • Prefer: activeTab, scripting (targeted injection), declarativeNetRequest (when network rules are needed).
    • Avoid: <all_urls>, *://*/*, broad tabs, unbounded host permissions.
  4. 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)
  5. 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.
  6. Side panel architecture must be modern.

    • Chrome: chrome.sidePanel + setPanelBehavior({ openPanelOnActionClick: true }).
    • Use setOptions() to vary panel path per-tab / conditionally.
    • Use layout awareness for LTR/RTL.
  7. Cross-browser: feature-detect, don’t UA-sniff.

    • Use conditional code paths (Chrome chrome.sidePanel vs Firefox browser.sidebarAction).
    • 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:

  1. Target + assumptions (1–3 lines)
  2. Recommended architecture (what runs where)
  3. Permissions proposal (minimal set) + privacy warnings
  4. State & persistence plan (storage choice) + lifecycle gotchas
  5. Code snippets (manifest + SW + UI + messaging)
  6. 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 chrome.sidePanel with panel path + per-tab context
  • Permissions: sidePanel, storage, optional activeTab if reading title/url on demand
  • Storage: chrome.storage.local keyed by tabId (ephemeral) + url (stable) with explicit privacy warning about storing URLs
  • Provide manifest + SW setPanelBehavior + 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 chrome.storage.local (or session 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 sidebar_action differences (no programmatic open; UX expectations)
  • Provide feature-detection wrapper and separate manifest keys
  • Recommend webextension-polyfill for promise-based APIs where appropriate

Best Practices / Pitfalls

  • Don’t request tabs 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 (alarms, message triggers, offscreen documents).
  • Side panel ≠ popup. Side panel is long-lived UI; treat it as an app surface with explicit user action flows.

Testing with Playwright

This skill includes comprehensive headless testing support via Playwright (Chrome 128+).

When to Use Playwright Testing

  • End-to-end extension testing in CI/CD
  • Automated popup/side panel UI testing
  • Content script injection verification
  • Service worker behavior validation
  • Cross-context messaging tests

Key Testing Capabilities

ComponentTest Approach
PopupLoad chrome-extension://ID/popup.html, interact with elements
Side PanelNavigate to panel URL, test UI state
Content ScriptInject into test page, verify DOM changes
Service WorkerSend messages, check storage, test alarms
Full FlowsMulti-step user journeys across all contexts

Headless Mode (New in Chrome 128+)

const context = await chromium.launchPersistentContext('', {
  headless: true,  // Now works with extensions!
  args: [
    `--load-extension=${EXTENSION_PATH}`,
    '--headless=new',  // Required flag
  ],
});

Quick Test Example

import { test, expect } from '@playwright/test';
import path from 'path';

const EXTENSION_PATH = path.join(__dirname, '../dist');

test('popup displays correctly', async ({ browser }) => {
  const context = await browser.newContext({
    args: [
      `--load-extension=${EXTENSION_PATH}`,
      `--disable-extensions-except=${EXTENSION_PATH}`,
    ],
  });
  
  // Get extension ID from service worker
  let [serviceWorker] = context.serviceWorkers();
  if (!serviceWorker) {
    serviceWorker = await context.waitForEvent('serviceworker');
  }
  const extensionId = serviceWorker.url().split('/')[2];
  
  // Test popup
  const popup = await context.newPage();
  await popup.goto(`chrome-extension://${extensionId}/popup.html`);
  await expect(popup.locator('h1')).toHaveText('My Extension');
});

Reference Files

  • references/playwright-testing/README.md - Overview and decision tree
  • references/playwright-testing/api.md - Complete API reference
  • references/playwright-testing/configuration.md - Setup and fixtures
  • references/playwright-testing/patterns.md - Testing scenarios
  • references/playwright-testing/gotchas.md - Pitfalls and workarounds

Resources

Install helpers are in resources/install.sh.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

arg-parser

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

large-file-refactorer

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

aquaria-docs

No summary provided by upstream source.

Repository SourceNeeds Review
Security

web-design-guidelines

Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".

Repository SourceNeeds Review
168.9K23Kvercel