Imported from LucasHenriqueDiniz/instagram-enhancer (
AGENTS.md). Install upstream withnpx skills add LucasHenriqueDiniz/instagram-enhancer. Copyright stays with the author.
AGENTS
Guidelines for contributors and coding agents working in this repository.
Goal
Build and maintain an Instagram-focused browser extension with clear user controls and safe defaults.
Understanding Instagram
Platform Architecture
Instagram is a complex single-page application (SPA) with dynamic DOM loading. Key characteristics:
- Dynamic Content Loading: Feed, stories, reels, and profile pages load content via infinite scroll and AJAX requests
- Class Obfuscation: Instagram uses minified, auto-generated CSS class names (e.g.,
_abc123d4) that change frequently - React-Based: Instagram runs on React with synthetic events; standard DOM listeners may miss events
- Frame Structure: Stories, reels, and modals are rendered in iframes or shadow DOMs
- Media Streaming: Video/audio use adaptive bitrate streaming (DASH/HLS); direct manipulation can break playback
Main Content Areas
- Feed: Home timeline with posts, carousel media, video, and reels
- Stories: Ephemeral content at top; auto-play videos, swipe navigation
- Reels: Short-form video feed with autoplay and infinite scroll
- Direct Messages (DMs): Real-time chat; requires careful DOM targeting
- Profile Pages: User/brand profiles with post grids and follower/following lists
- Search/Explore: Algorithm-driven content discovery with dynamic loading
Chrome Extension Best Practices
Manifest & Permissions
-
Principle of Least Privilege: Request only necessary permissions
content_scripts: Inject into Instagram pages onlystorage: For user settings (sync) and runtime state (local)webRequest/declarativeNetRequest: Only if filtering contentactiveTab: For popup interactions requiring current tab context
-
Manifest V3 Compliance (Required for modern Chrome):
- Use Service Workers instead of background pages
- Replace
webRequestwithdeclarativeNetRequest - Use
executeScriptinstead of injected scripts for sensitive operations - Content Security Policy (CSP) must be explicit and minimal
-
Host Permissions:
"host_permissions": [ "*://www.instagram.com/*", "*://www.instagram.com/graphql/*" ]
Content Script Architecture
-
Injection Strategy:
- Content scripts execute in an isolated world; direct DOM access is sandboxed
- Use
window.postMessage()to communicate with page context when needed - Avoid
eval()or dynamic script injection due to CSP restrictions
-
Message Passing:
- Use
chrome.runtime.sendMessage()for popup ↔ background - Use
chrome.tabs.sendMessage()for popup ↔ content script - Keep messages small; large data should use
chrome.storage
- Use
-
DOM Interaction:
- Inject minimal, scoped styles via
<style>tags, not<link>(CSP) - Use event delegation for dynamically loaded content
- Clean up event listeners to avoid memory leaks
- Inject minimal, scoped styles via
Performance Optimization
-
Avoid Polling:
- Use
MutationObserverfor DOM changes instead ofsetInterval() - Debounce observer callbacks to prevent thrashing
- Use
-
Lazy Loading:
- Load heavy logic only when user interacts with features
- Use dynamic imports for optional functionality
-
Memory Management:
- Unsubscribe from observers when features are disabled
- Remove event listeners in cleanup functions
- Use
WeakMapfor element-specific data to enable garbage collection
Product Rules
-
Keep features optional behind settings toggles
- Default to "off" for non-essential features
- Persist user preferences in
chrome.storage.sync
-
Do not break Instagram core navigation or media playback
- Never intercept native scroll events on feed/reels
- Avoid modifying video/audio elements directly
- Test all features against latest Instagram UI (re-tests when Instagram updates)
-
Prefer resilient selectors and mutation observers over brittle class-only selectors
- Use attribute selectors:
[aria-label="Like"],[role="button"] - Combine multiple selectors for robustness:
article button[aria-label*="Like"], article [role="button"][aria-label*="Like"] - Test selectors against Stories, Reels, Feed, and mobile web layouts
- Use attribute selectors:
-
Avoid aggressive polling when an observer can do the job
- Use
MutationObserverfor content changes - Set
{ subtree: true, childList: true }for deep monitoring - Throttle callbacks to max 200ms for responsiveness
- Use
-
Keep UI labels simple and translatable
- Use i18n keys for all user-facing text
- Keep labels under 30 characters
- Avoid technical jargon in UI
Code Rules
General
-
TypeScript only for source files in
src/- Use strict mode:
"strict": trueintsconfig.json - No
anytypes; useunknownand type narrowing - Enable
noUncheckedIndexedAccessto catch array access bugs
- Use strict mode:
-
Keep content-script logic modular and idempotent
- Content scripts can run multiple times; design for re-execution
- Avoid global state; use closures for encapsulation
- Export pure functions and factories
-
Do not introduce blocking network calls in hot DOM loops
- Batch API calls with
Promise.all() - Use debouncing for repeated triggers
- Move fetch calls outside render/observer callbacks
- Batch API calls with
-
Use storage correctly:
chrome.storage.sync: User settings, preferences (cross-device)chrome.storage.local: Runtime cache, temporary state (local only)- Always handle quota limits (
chrome.storage.QUOTA_BYTES)
-
Any new permission in
manifest.jsonmust have a matching feature justification inREADME.md- Document why the permission is needed
- Explain what data is accessed and how it's used
- Link to relevant issues/features
DOM & Selectors
-
Use data attributes for custom hooks instead of relying on class names:
<button class="_abc123" data-testid="like-btn">Like</button> -
Avoid fragile XPath; use CSS selectors where possible
-
Test selectors against:
- Desktop feed, stories, reels, DMs, explore
- Mobile web layout
- Dark mode (if adding styles)
Error Handling
- Log errors with context:
console.error('Feature X failed:', { selector, error }) - Never silently fail in critical paths
- Provide user-friendly error messages in UI
Testing & Validation
- Test on actual Instagram (not mocked): Use staging/sandbox accounts
- Clear browser cache between tests (
chrome://settings/clearBrowserData) - Check for memory leaks: DevTools → Memory → Take heap snapshot before/after feature use
Verification Checklist
Before finishing a change, validate:
-
Type Safety:
npm run typecheck(no errors)- ESLint checks:
npm run lint(if configured)
-
Build & Loading:
npm run build(no errors)- Extension loads in
chrome://extensionswith no errors - Verify "Errors" tab in extension details (chrome://extensions) is clean
-
Core Functionality:
- Main Instagram features still work: feed scroll, video play, stories swipe
- Your feature works on feed, stories, reels, and profile pages
- Settings toggle on/off works correctly
- No console errors/warnings related to the extension
-
Performance:
- Page load time unchanged (DevTools → Performance)
- No memory leaks (DevTools → Memory)
- No excessive DOM mutations (DevTools → Performance → Record)
-
Compatibility:
- Test on Chrome, Edge, Brave (all Chromium-based)
- Test on mobile web (chrome://inspect)
Common Pitfalls & Solutions
| Problem | Solution |
|---|---|
| Feature breaks after Instagram update | Use resilient selectors + test regularly |
| Content script runs multiple times | Use idempotent logic, check for existing listeners |
| Extension blocks video playback | Avoid modifying <video> or <audio> directly |
| Performance degrades with feature toggle | Use MutationObserver instead of polling; debounce callbacks |
| Selector matches too broadly | Use multiple constraints: article [role="button"][aria-label*="Like"] |
| Data persists after uninstall | Use chrome.storage; it auto-clears on uninstall |
| Extension conflicts with other extensions | Use unique data-attributes, namespaced CSS classes |
Future Enhancements
- Improve selector strategy for stories/reels edge cases
- Add finer ad filters with user-defined keywords
- Add keyboard shortcuts for media actions
- Performance: Implement content script code-splitting for Manifest V3
- Accessibility: Add focus management for overlays and modals
- i18n: Add support for multiple languages beyond English