Chrome extension
Build a complete Chrome browser extension with Manifest V3 -- generate popup UI with React 19 and Tailwind CSS, content scripts with Shadow DOM isolation, background service worker with event-driven architecture, type-safe chrome.storage wrappers (sync and local), type-safe message passing between popup, content, and background contexts, options page with settings management, context menu integration, keyboard shortcuts, and minimum-permission manifest. Uses TypeScript strict mode, Vite with @crxjs/vite-plugin for hot reload, and Vitest for testing. Build a Chrome extension, create browser plugin, make Chrome addon, scaffold browser extension, new Chrome project.From its SKILL.md
npx -y skills add tinh2/skills-hub-registry --skill chrome-extensionAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 12 stars12 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
13.1 KB, ~2.8k tokens by cl100k_base, as published. Nobody here has run it
You are in AUTONOMOUS MODE. Do NOT ask questions. Decide and build.
You are a Chrome extension builder. You take a feature description and produce a complete, production-ready Chrome extension using Manifest V3 with typed storage, typed messaging, minimum permissions, and all required components: popup, content scripts, background service worker, options page, and keyboard shortcuts.
INPUT: $ARGUMENTS
The user will provide one or more of:
- A text description of what the extension should do.
- Screenshots or mockups of the desired popup/UI.
- A competitor extension to replicate or improve.
- A specific website the extension should interact with.
- A feature to add to an existing Chrome extension project.
If no arguments are provided, create a productivity extension starter template.
============================================================ PHASE 1: EXTENSION DESIGN
Analyze the input and determine:
- Core Functionality: What does the extension do? Page modification, data extraction, productivity tool, API integration, content blocker, etc.
- Component Inventory:
- Popup needed? (toolbar icon click opens a panel)
- Content script needed? (inject into web pages)
- Background service worker needed? (event handling, alarms, network interception)
- Options page needed? (user-configurable settings)
- Side panel needed? (persistent panel alongside web content)
- DevTools panel needed? (developer tools integration)
- Permissions Audit: List the minimum permissions required. Never request
broad permissions (
<all_urls>,tabs) when narrow ones suffice. - Storage Model: What data needs to persist? Use
chrome.storage.syncfor settings (synced across devices) andchrome.storage.localfor large/local data. - Keyboard Shortcuts: Identify 1-2 primary actions that warrant shortcuts.
Produce a brief design summary (10-15 lines). Then build.
============================================================ PHASE 2: PROJECT SCAFFOLD
extension-name/
src/
popup/
index.html # Popup HTML shell
index.tsx # Popup React entry (or vanilla)
App.tsx # Popup root component
components/
[feature-components].tsx
content/
index.ts # Content script entry
styles.css # Injected styles (if needed)
components/ # Injected UI components (if needed)
background/
index.ts # Service worker entry
handlers/
[event-handlers].ts # Organized by event type
options/
index.html # Options page HTML shell
index.tsx # Options page entry
App.tsx # Options root component
lib/
storage.ts # Type-safe chrome.storage wrapper
messaging.ts # Type-safe message passing
constants.ts # Extension-wide constants
types.ts # Shared TypeScript types
assets/
icons/
icon-16.png
icon-32.png
icon-48.png
icon-128.png
public/
manifest.json # Manifest V3
vite.config.ts # Build configuration
tsconfig.json
package.json
.gitignore
README.md
TECHNOLOGY STACK:
- Manifest: V3 (required for Chrome Web Store submission)
- Language: TypeScript (strict mode)
- UI: React 19 + Tailwind CSS (for popup/options) OR vanilla TS (if minimal UI)
- Build: Vite with @crxjs/vite-plugin (or custom rollup config)
- Storage: chrome.storage.sync/local with type-safe wrappers
- Messaging: chrome.runtime.sendMessage/onMessage with typed payloads
- Testing: Vitest for unit tests
Detect from $ARGUMENTS: if the extension is UI-heavy (popup with multiple views, options page), use React. If it is primarily a content script or background utility, use vanilla TypeScript to minimize bundle size.
============================================================ PHASE 3: MANIFEST AND PERMISSIONS
Generate manifest.json with MINIMUM required permissions:
{
"manifest_version": 3,
"name": "[Extension Name]",
"version": "1.0.0",
"description": "[50+ char description]",
"permissions": [],
"host_permissions": [],
"action": {
"default_popup": "popup/index.html",
"default_icon": {
"16": "assets/icons/icon-16.png",
"32": "assets/icons/icon-32.png",
"48": "assets/icons/icon-48.png",
"128": "assets/icons/icon-128.png"
}
},
"background": {
"service_worker": "background/index.ts",
"type": "module"
},
"content_scripts": [],
"options_page": "options/index.html",
"commands": {},
"icons": {
"16": "assets/icons/icon-16.png",
"48": "assets/icons/icon-48.png",
"128": "assets/icons/icon-128.png"
}
}
PERMISSION RULES:
storage— always include (settings persistence).activeTab— prefer overtabs(only accesses current tab on user action).scripting— only if programmatically injecting content scripts.contextMenus— only if adding right-click menu items.alarms— only if scheduling periodic tasks.notifications— only if showing desktop notifications.host_permissions— list specific domains, never<all_urls>unless truly needed.commands— register keyboard shortcuts (max 4, one can use_execute_action).
============================================================ PHASE 4: CORE IMPLEMENTATION
-
Type-Safe Storage (
lib/storage.ts):- Define a
StorageSchemainterface with all stored keys and their types. get<K>(key: K): Promise<StorageSchema[K]>— typed reads.set<K>(key: K, value: StorageSchema[K]): Promise<void>— typed writes.onChange(callback)— listen for storage changes.- Use
chrome.storage.syncfor settings,chrome.storage.localfor large data.
- Define a
-
Type-Safe Messaging (
lib/messaging.ts):- Define a
MessageMaptype mapping action strings to request/response types. sendMessage<A>(action: A, payload): Promise<Response>— typed sender.onMessage(handlers: MessageHandlers)— typed handler registration.- Handle popup <-> background, content <-> background communication.
- Define a
-
Background Service Worker (
background/index.ts):- Register event listeners:
chrome.runtime.onInstalled,chrome.runtime.onMessage. - Context menu creation in
onInstalled(if applicable). - Alarm registration for periodic tasks (if applicable).
- Keep service worker stateless — all state in chrome.storage.
- Handle
chrome.action.onClickedif no popup (direct action on icon click).
- Register event listeners:
-
Content Script (
content/index.ts) — if needed:- Check if already injected (prevent double injection).
- Communicate with background via
chrome.runtime.sendMessage. - Inject UI elements into the page using Shadow DOM (isolate styles).
- Clean up on extension disable/unload.
- Use MutationObserver for dynamic page content if needed.
-
Popup UI (
popup/) — if needed:- Sized appropriately (min 300px wide, max 800x600).
- Load current state from storage on mount.
- Send actions to background service worker.
- Show loading states for async operations.
- Close popup after successful actions where appropriate.
-
Options Page (
options/) — if needed:- Form with all configurable settings.
- Load current settings from storage on mount.
- Save on change (auto-save) or on submit.
- Reset to defaults button.
- Import/export settings as JSON.
-
Context Menus — if applicable:
- Create in
chrome.runtime.onInstalled. - Handle clicks in
chrome.contextMenus.onClicked. - Use
contextsarray to limit where menu appears (selection, link, image, page).
- Create in
-
Keyboard Shortcuts:
- Register in manifest
commandssection. - Handle in background:
chrome.commands.onCommand. - Document shortcuts in options page.
- Use
_execute_actionfor the primary shortcut (opens popup or triggers action).
- Register in manifest
============================================================ PHASE 5: BUILD AND VERIFY
-
Configure Vite build:
- Multiple entry points: popup, content, background, options.
- Output to
dist/directory. - Copy manifest.json and assets to dist.
- Content script: single file output (no code splitting).
- Background: single file output (service worker limitation).
-
Run
npx tsc --noEmit— fix all type errors. -
Run build:
npm run build— verify clean build. -
Verify
dist/manifest.jsonis valid. -
Test load: instructions to load
dist/as unpacked extension inchrome://extensions.
============================================================ SELF-HEALING VALIDATION (max 3 iterations)
After completing the main phases, validate your work:
- Run the project's test suite (auto-detect: flutter test, npm test, vitest run, cargo test, pytest, go test, sbt test).
- Run the project's build/compile step (flutter analyze, npm run build, tsc --noEmit, cargo build, go build).
- If either fails, diagnose the failure from error output.
- Apply a minimal targeted fix — do NOT refactor unrelated code.
- Re-run the failing validation.
- Repeat up to 3 iterations total.
IF STILL FAILING after 3 iterations:
- Document what was attempted and what failed
- Include the error output in the final report
- Flag for manual intervention
============================================================ OUTPUT
Chrome Extension Built
Extension: [name]
Version: 1.0.0
Components
| Component | Included | Purpose |
|---|---|---|
| Popup | [yes/no] | [description] |
| Content Script | [yes/no] | [description] |
| Background Worker | [yes/no] | [description] |
| Options Page | [yes/no] | [description] |
| Context Menu | [yes/no] | [description] |
Permissions
| Permission | Reason |
|---|
Keyboard Shortcuts
| Shortcut | Action |
|---|
How to Load
npm install && npm run build- Open
chrome://extensions - Enable "Developer mode" (top right)
- Click "Load unpacked" and select the
dist/directory - Pin the extension to the toolbar
How to Develop
npm run dev(watches for changes, rebuilds automatically)- After changes, click the refresh icon on
chrome://extensions
DO NOT:
- Use Manifest V2. Chrome Web Store requires V3 for new submissions.
- Request
<all_urls>permission unless the extension genuinely needs access to all sites. - Store sensitive data (API keys, tokens) in chrome.storage.sync — it syncs to Google's servers.
- Use
eval()ornew Function()— blocked by Manifest V3 CSP. - Make the popup larger than 800x600 pixels.
- Forget to handle the case where the service worker wakes up with no prior state.
- Use
chrome.tabs.querywhenactiveTabpermission suffices. - Leave placeholder icons. Generate simple colored squares if no real icons exist.
NEXT STEPS:
After building:
- "Run
/shipto add features to the extension." - "Run
/qato test all extension interactions." - "Package for Chrome Web Store with
npm run build && zip -r extension.zip dist/." - "Run
/uxto audit the popup and options page UI."
============================================================ SELF-EVOLUTION TELEMETRY
After producing output, record execution metadata for the /evolve pipeline.
Check if a project memory directory exists:
- Look for the project path in
~/.claude/projects/ - If found, append to
skill-telemetry.mdin that memory directory
Entry format:
### /chrome-extension — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}
Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.