distributions/claude/skills/browser-extension-patterns/SKILL.md
Build browser extensions with Manifest V3 for Chrome, Firefox, and cross-browser compatibility. Covers content scripts, background workers, popup UI, storage APIs, and extension messaging. Triggers on browser extension development, Manifest V3, or Chrome extension requests.
npx skillsauth add a-organvm/a-i--skills browser-extension-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build cross-browser extensions with Manifest V3 architecture.
my-extension/
├── manifest.json # Extension manifest
├── background/
│ └── service-worker.js # Background service worker
├── content/
│ └── content-script.js # Injected into web pages
├── popup/
│ ├── popup.html # Popup UI
│ ├── popup.js # Popup logic
│ └── popup.css # Popup styles
├── options/
│ ├── options.html # Settings page
│ └── options.js
├── icons/
│ ├── icon-16.png
│ ├── icon-48.png
│ └── icon-128.png
└── _locales/ # Internationalization
└── en/messages.json
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "Brief description of what it does",
"permissions": ["storage", "activeTab"],
"host_permissions": ["https://*.example.com/*"],
"background": {
"service_worker": "background/service-worker.js"
},
"content_scripts": [{
"matches": ["https://*.example.com/*"],
"js": ["content/content-script.js"],
"css": ["content/content-style.css"],
"run_at": "document_idle"
}],
"action": {
"default_popup": "popup/popup.html",
"default_icon": {
"16": "icons/icon-16.png",
"48": "icons/icon-48.png",
"128": "icons/icon-128.png"
}
},
"options_page": "options/options.html",
"icons": {
"16": "icons/icon-16.png",
"48": "icons/icon-48.png",
"128": "icons/icon-128.png"
}
}
// background/service-worker.js
// Installation
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
chrome.storage.local.set({ settings: { enabled: true, theme: 'light' } });
}
});
// Message handling from content scripts and popup
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.type) {
case 'getData':
fetchData(message.url).then(sendResponse);
return true; // Async response
case 'updateBadge':
chrome.action.setBadgeText({ text: String(message.count) });
break;
}
});
// Alarm-based periodic tasks (replaces MV2 persistent background)
chrome.alarms.create('sync', { periodInMinutes: 30 });
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === 'sync') syncData();
});
// content/content-script.js
// DOM manipulation on target pages
function enhancePage() {
const elements = document.querySelectorAll('.target-class');
elements.forEach(el => {
const badge = document.createElement('span');
badge.className = 'my-extension-badge';
badge.textContent = 'Enhanced';
el.appendChild(badge);
});
}
// Run when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', enhancePage);
} else {
enhancePage();
}
// Communicate with background
async function requestData(url) {
return chrome.runtime.sendMessage({ type: 'getData', url });
}
// Listen for messages from background/popup
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'getPageData') {
sendResponse({ title: document.title, url: location.href });
}
});
// Chrome storage API (synced across devices)
const storage = {
async get(key) {
const result = await chrome.storage.sync.get(key);
return result[key];
},
async set(key, value) {
await chrome.storage.sync.set({ [key]: value });
},
async getLocal(key) {
const result = await chrome.storage.local.get(key);
return result[key];
},
onChange(callback) {
chrome.storage.onChanged.addListener((changes, area) => {
callback(changes, area);
});
}
};
// Usage
await storage.set('settings', { theme: 'dark', enabled: true });
const settings = await storage.get('settings');
<!-- popup/popup.html -->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="popup.css">
</head>
<body>
<div id="app">
<h2>My Extension</h2>
<label>
<input type="checkbox" id="enabled"> Enabled
</label>
<div id="status"></div>
</div>
<script src="popup.js"></script>
</body>
</html>
// popup/popup.js
document.addEventListener('DOMContentLoaded', async () => {
const settings = await chrome.storage.sync.get('settings');
document.getElementById('enabled').checked = settings.settings?.enabled;
document.getElementById('enabled').addEventListener('change', async (e) => {
await chrome.storage.sync.set({
settings: { ...settings.settings, enabled: e.target.checked }
});
// Notify content scripts
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
chrome.tabs.sendMessage(tab.id, { type: 'settingsChanged', enabled: e.target.checked });
});
});
// Polyfill for Firefox WebExtensions API
const browser = globalThis.browser || globalThis.chrome;
// Feature detection
const isFirefox = typeof browser !== 'undefined' && browser.runtime?.getBrowserInfo;
const isChrome = typeof chrome !== 'undefined' && chrome.runtime?.id;
{
"background": {
"scripts": ["background/service-worker.js"]
},
"browser_specific_settings": {
"gecko": {
"id": "[email protected]",
"strict_min_version": "109.0"
}
}
}
| Permission | When | Impact |
|-----------|------|--------|
| activeTab | Need current tab only | Low (user-triggered) |
| storage | Need to save settings | Low |
| tabs | Need tab URLs/titles | Medium |
| host_permissions | Need page access | High (shows warning) |
| <all_urls> | Need all page access | Very High (avoid if possible) |
Principle: Request minimum permissions. Use activeTab over broad host permissions when possible.
<all_urls> permission — Request only the hosts you needchrome.storage APIruntime.onInstalled to handle updates and cleanupdevelopment
Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks
development
Conducts a full automated autopsy of the current workspace directory to map files, identifies structural issues, proposes a restructuring plan (the signal), and establishes unified governance using templates. Use this skill when a user asks to map, restructure, reorganize, or apply new governance to an existing messy repository.
testing
Design engaging workshops, conference talks, and educational presentations. Covers learning objectives, activity design, slide craft, and facilitation techniques. Triggers on workshop design, presentation prep, talk structure, or training session requests.
development
Designs reliable webhook systems with proper delivery guarantees, retry logic, signature verification, and idempotent processing for event-driven integrations.