Platform Development6 min read

Chrome Extension Development

Build Chrome extensions with Manifest V3: service workers, content scripts, popup UIs, storage sync, and Chrome API permissions.

chrome-extensionjavascriptbrowserextension

Chrome extensions augment the browser with custom functionality - from ad blockers to developer tools to productivity apps. Manifest V3 (current standard) uses service workers instead of background pages, requiring a different architecture for persistent state.

Use Manifest V3 for all new extensions. Request only the minimum permissions needed (users see them during install). Use service workers for background logic. Store state in `chrome.storage.local/sync`. Test with `chrome://extensions` developer mode.

Workflow

  1. Structure your extension with Manifest V3manifest.json is the entry point that declares all permissions, scripts, and pages.
  2. Build background service workersService workers replace background pages in MV3 - they're event-driven and don't persist between events.
  3. Write content scripts for page injectionContent scripts run in the context of web pages - they can read and modify the DOM.
  4. Build the popup UIThe popup is the primary user interaction point - it should be fast and immediately useful.
  5. Handle permissions and storage correctlyOver-broad permissions trigger user warnings and store rejection; wrong storage API loses data.

Output Format

manifest.json with minimal permissions, service worker for background, content script for page interaction, popup UI, chrome.storage for persistence.

Examples

Background message handler: `chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "getPageTitle") { chrome.tabs.query({ active: true }, ([tab]) => sendResponse({ title: tab.title })); return true; // async response } })`
Content script → background: `const response = await chrome.runtime.sendMessage({ action: "fetchData", url: window.location.href }); document.body.insertAdjacentHTML("afterbegin", `<div>${response.data}</div>`)`
Storage: `await chrome.storage.local.set({ userPrefs: { theme: "dark", enabled: true } }); const { userPrefs } = await chrome.storage.local.get("userPrefs")`

Edge Cases & Gotchas

  • Service worker lifetime: MV3 service workers can be terminated at any time; never assume they're running between events; use chrome.storage for all state
  • CSP in popup: extension popup pages have strict CSP; no inline scripts or eval(); use event listeners in separate JS files
  • Wasm and eval: MV3 restricts arbitrary code execution; use wasm-eval or `wasm_unsafe_eval` CSP directive for WebAssembly use cases

When to Break These Rules

  • For browser automation or scraping tools used by developers (not published to the Chrome Web Store), Playwright or Puppeteer are simpler than building a full extension.

Reference Files

  • Chrome Extension MV3: https://developer.chrome.com/docs/extensions/develop/
  • Chrome APIs: https://developer.chrome.com/docs/extensions/reference/api/
  • Extension samples: https://github.com/GoogleChrome/chrome-extensions-samples

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.