
Content Script Developer
- 133 installs
- 31 repo stars
- Updated August 2, 2026
- shipshitdev/library
Implement browser extension content scripts that inject UI, observe DOM changes, message background workers, and interact safely with third-party pages.
About
Specializes in browser extension content-script development: DOM injection, background messaging, permissions, CSP edge cases, and resilient behavior on dynamic third-party sites so extension features integrate cleanly with the open web.
- DOM injection and isolated-world patterns
- Messaging between content and background scripts
- Host permission and CSP considerations
- Mutation observers and SPA compatibility
- Safe handling of untrusted page context
Content Script Developer by the numbers
- 133 all-time installs (skills.sh)
- +1 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #984 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/shipshitdev/library --skill content-script-developerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 133 |
|---|---|
| repo stars | ★ 31 |
| Last updated | August 2, 2026 |
| Repository | shipshitdev/library ↗ |
What it does
Implement browser extension content scripts that inject UI, observe DOM changes, message background workers, and interact safely with third-party pages.
Files
Content Script Developer
You build reliable, low-impact content scripts for browser extensions (Chrome MV3). You focus on stable DOM integration, safe styling, messaging, and performance on SPA-heavy sites.
When to Use
- Building or updating a content script
- Injecting UI into third-party pages
- Scraping or reading page state in a browser extension
- Handling SPA navigation changes or dynamic DOM updates
Core Constraints
- Content scripts run in an isolated world; page JS scope is not shared.
- Avoid polluting the host page (global styles, conflicting IDs/classes).
- Be idempotent: injection should not duplicate on re-run.
- Prefer robust selectors over brittle class chains.
- Never block the main thread; throttle observers and event handlers.
Workflow
1) Understand the Target Page
- Identify stable anchors (data attributes, IDs, landmark roles).
- Note SPA navigation patterns (URL changes, DOM root swaps).
- Decide what you need: read-only scrape vs UI injection.
2) Plan Injection Safely
- Create a single root container for your UI.
- Use a shadow root if CSS conflicts are likely.
- Add styles with a unique prefix or scoped to your root.
- Ensure cleanup hooks if the page swaps roots.
3) Handle Dynamic Pages
- Use a MutationObserver for DOM changes.
- Throttle work with
requestAnimationFrameor debouncing. - Re-check anchors on navigation events.
4) Message and Store Data
- Use
chrome.runtime.sendMessagefor background/service worker calls. - Use
chrome.storagefor persistent state. - Keep tokens or sensitive data in extension storage, not DOM.
5) Accessibility and UX
- Keyboard-focusable UI elements.
- Visible focus styles.
- ARIA labels for controls.
Patterns and Snippets
Idempotent UI Injection
const ROOT_ID = 'ext-root';
export function ensureRoot() {
let root = document.getElementById(ROOT_ID);
if (root) return root;
root = document.createElement('div');
root.id = ROOT_ID;
root.setAttribute('data-ext-root', 'true');
document.body.appendChild(root);
return root;
}Safe Styling (Scoped)
const styleId = 'ext-style';
function injectStyles(css: string) {
if (document.getElementById(styleId)) return;
const style = document.createElement('style');
style.id = styleId;
style.textContent = css;
document.head.appendChild(style);
}MutationObserver with Throttle
let scheduled = false;
const observer = new MutationObserver(() => {
if (scheduled) return;
scheduled = true;
requestAnimationFrame(() => {
scheduled = false;
// re-check anchors or update UI
});
});
observer.observe(document.body, { childList: true, subtree: true });Messaging to Background
async function fetchData(payload: Record<string, unknown>) {
return await chrome.runtime.sendMessage({ type: 'FETCH_DATA', payload });
}Reliability Checklist
- UI injection is idempotent
- Styles are scoped or shadow-rooted
- Observers are throttled and cleaned up
- Messaging uses explicit message types
- Host page performance remains stable
Common Pitfalls
- Injecting the same UI multiple times on SPA navigation
- Using brittle selectors that break on minor DOM changes
- Global CSS that overrides host styles
- Heavy MutationObserver handlers without throttling
Notes
- Prefer small, composable helpers over large one-off scripts.
- Keep extension logging prefixed and easy to disable in production.
{
"name": "content-script-developer",
"version": "1.0.0",
"description": "Expert in browser extension content scripts, DOM integration, and safe page augmentation across mode",
"author": {
"name": "Ship Shit Dev",
"email": "hello@shipshit.dev",
"url": "https://shipshit.dev"
},
"license": "MIT",
"skills": "."
}