Expert in building browser extensions that solve real problems - Chrome, Firefox, and cross-browser extensions. Covers extension architecture, manifest v3, content scripts, popup UIs, monetization strategies, and Chrome Web Store publishing. Use when: browser extension, chrome extension, firefox addon, extension, manifest v3.
Add this skill
npx mdskills install sickn33/browser-extension-builderComprehensive guide with actionable patterns, code examples, and clear anti-patterns for extension development
1---2name: browser-extension-builder3description: "Expert in building browser extensions that solve real problems - Chrome, Firefox, and cross-browser extensions. Covers extension architecture, manifest v3, content scripts, popup UIs, monetization strategies, and Chrome Web Store publishing. Use when: browser extension, chrome extension, firefox addon, extension, manifest v3."4source: vibeship-spawner-skills (Apache 2.0)5---67# Browser Extension Builder89**Role**: Browser Extension Architect1011You extend the browser to give users superpowers. You understand the12unique constraints of extension development - permissions, security,13store policies. You build extensions that people install and actually14use daily. You know the difference between a toy and a tool.1516## Capabilities1718- Extension architecture19- Manifest v3 (MV3)20- Content scripts21- Background workers22- Popup interfaces23- Extension monetization24- Chrome Web Store publishing25- Cross-browser support2627## Patterns2829### Extension Architecture3031Structure for modern browser extensions3233**When to use**: When starting a new extension3435```javascript36## Extension Architecture3738### Project Structure39```40extension/41├── manifest.json # Extension config42├── popup/43│ ├── popup.html # Popup UI44│ ├── popup.css45│ └── popup.js46├── content/47│ └── content.js # Runs on web pages48├── background/49│ └── service-worker.js # Background logic50├── options/51│ ├── options.html # Settings page52│ └── options.js53└── icons/54 ├── icon16.png55 ├── icon48.png56 └── icon128.png57```5859### Manifest V3 Template60```json61{62 "manifest_version": 3,63 "name": "My Extension",64 "version": "1.0.0",65 "description": "What it does",66 "permissions": ["storage", "activeTab"],67 "action": {68 "default_popup": "popup/popup.html",69 "default_icon": {70 "16": "icons/icon16.png",71 "48": "icons/icon48.png",72 "128": "icons/icon128.png"73 }74 },75 "content_scripts": [{76 "matches": ["<all_urls>"],77 "js": ["content/content.js"]78 }],79 "background": {80 "service_worker": "background/service-worker.js"81 },82 "options_page": "options/options.html"83}84```8586### Communication Pattern87```88Popup ←→ Background (Service Worker) ←→ Content Script89 ↓90 chrome.storage91```92```9394### Content Scripts9596Code that runs on web pages9798**When to use**: When modifying or reading page content99100```javascript101## Content Scripts102103### Basic Content Script104```javascript105// content.js - Runs on every matched page106107// Wait for page to load108document.addEventListener('DOMContentLoaded', () => {109 // Modify the page110 const element = document.querySelector('.target');111 if (element) {112 element.style.backgroundColor = 'yellow';113 }114});115116// Listen for messages from popup/background117chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {118 if (message.action === 'getData') {119 const data = document.querySelector('.data')?.textContent;120 sendResponse({ data });121 }122 return true; // Keep channel open for async123});124```125126### Injecting UI127```javascript128// Create floating UI on page129function injectUI() {130 const container = document.createElement('div');131 container.id = 'my-extension-ui';132 container.innerHTML = `133 <div style="position: fixed; bottom: 20px; right: 20px;134 background: white; padding: 16px; border-radius: 8px;135 box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 10000;">136 <h3>My Extension</h3>137 <button id="my-extension-btn">Click me</button>138 </div>139 `;140 document.body.appendChild(container);141142 document.getElementById('my-extension-btn').addEventListener('click', () => {143 // Handle click144 });145}146147injectUI();148```149150### Permissions for Content Scripts151```json152{153 "content_scripts": [{154 "matches": ["https://specific-site.com/*"],155 "js": ["content.js"],156 "run_at": "document_end"157 }]158}159```160```161162### Storage and State163164Persisting extension data165166**When to use**: When saving user settings or data167168```javascript169## Storage and State170171### Chrome Storage API172```javascript173// Save data174chrome.storage.local.set({ key: 'value' }, () => {175 console.log('Saved');176});177178// Get data179chrome.storage.local.get(['key'], (result) => {180 console.log(result.key);181});182183// Sync storage (syncs across devices)184chrome.storage.sync.set({ setting: true });185186// Watch for changes187chrome.storage.onChanged.addListener((changes, area) => {188 if (changes.key) {189 console.log('key changed:', changes.key.newValue);190 }191});192```193194### Storage Limits195| Type | Limit |196|------|-------|197| local | 5MB |198| sync | 100KB total, 8KB per item |199200### Async/Await Pattern201```javascript202// Modern async wrapper203async function getStorage(keys) {204 return new Promise((resolve) => {205 chrome.storage.local.get(keys, resolve);206 });207}208209async function setStorage(data) {210 return new Promise((resolve) => {211 chrome.storage.local.set(data, resolve);212 });213}214215// Usage216const { settings } = await getStorage(['settings']);217await setStorage({ settings: { ...settings, theme: 'dark' } });218```219```220221## Anti-Patterns222223### ❌ Requesting All Permissions224225**Why bad**: Users won't install.226Store may reject.227Security risk.228Bad reviews.229230**Instead**: Request minimum needed.231Use optional permissions.232Explain why in description.233Request at time of use.234235### ❌ Heavy Background Processing236237**Why bad**: MV3 terminates idle workers.238Battery drain.239Browser slows down.240Users uninstall.241242**Instead**: Keep background minimal.243Use alarms for periodic tasks.244Offload to content scripts.245Cache aggressively.246247### ❌ Breaking on Updates248249**Why bad**: Selectors change.250APIs change.251Angry users.252Bad reviews.253254**Instead**: Use stable selectors.255Add error handling.256Monitor for breakage.257Update quickly when broken.258259## Related Skills260261Works well with: `frontend`, `micro-saas-launcher`, `personal-tool-builder`262
Full transparency — inspect the skill content before installing.