A Chrome DevTools extension for inspecting frames and postMessage communication between iframes, providing a Network-tab-like experience with a sortable/filterable table and detail panel.
- Table View: Messages displayed in a sortable table with customizable columns
- Split-Pane UI: Click a message to see full details while keeping the list visible
- Filtering: Filter by type, origin, direction, or free text (e.g.,
type:resize,dir:sending) - Column Customization: Right-click header to show/hide columns
- Bidirectional Capture: Captures both outgoing
postMessage()calls and incomingmessageevents - Preserve Log: Option to retain messages across page navigations
├── manifest.json # Chrome extension manifest (Manifest V3)
├── devtools.html # DevTools page entry point
├── devtools.js # DevTools panel initialization
├── panel.html # The Frames panel UI
├── panel.css # Panel styles (DevTools-like appearance)
├── panel.js # Panel logic (table, filtering, detail view)
├── injected.js # Injected into page context (postMessage interception)
├── content.js # Content script (event bridge to service worker)
├── background.js # Service worker (message routing)
└── test/ # Test pages for manual testing
- Clone or download this repository
- Open Chrome and navigate to
chrome://extensions/ - Enable "Developer mode" (toggle in top right)
- Click "Load unpacked" and select the project folder
- Open DevTools on any page - you'll see a "Frames" tab
- Open DevTools (F12 or right-click → Inspect)
- Navigate to the "Frames" tab
- Interact with the page to generate postMessage traffic
- Messages appear in the table as they're captured
resize- Messages containing "resize" in data previewtype:resize- Messages withdata.type === "resize"origin:example.com- Messages from origins containing "example.com"dir:sending- Outgoing messages onlydir:receiving- Incoming messages only
Multiple terms are AND'd together.
Open test/test-page.html in Chrome (via a local server) to test the extension with sample iframes.
cd test && python -m http.server 8000
# Then open http://localhost:8000/test-page.htmlThe extension is designed to be minimally invasive:
- On-demand injection: Scripts are only injected into pages when you open the Frames panel for that tab. Pages you don't inspect remain untouched.
- Popup capture: When you open a popup from a monitored tab, the extension automatically enables monitoring for the popup and buffers early messages until you view its panel.
- Persistent monitoring: Once enabled, monitoring stays active even when the panel isn't visible or DevTools is closed. Reload the page to disable monitoring.
Page Context Isolated World
──────────── ──────────────
Frame A ┌─────────────────────┐ CustomEvent ┌─────────────────┐
│ injected.js │ ───────────────►│ content.js │──┐
│ (wraps postMessage)│ │ (event bridge) │ │
└─────────────────────┘ └─────────────────┘ │
│
Frame B ┌─────────────────────┐ CustomEvent ┌─────────────────┐ │
│ injected.js │ ───────────────►│ content.js │──┼──► Service Worker ──► DevTools Panel
└─────────────────────┘ └─────────────────┘ │
Content scripts run in Chrome's isolated world and cannot directly intercept page JavaScript. The extension uses a two-script approach:
- injected.js - Injected into the page's main world to wrap
window.postMessageand listen formessageevents - content.js - Receives CustomEvents from injected.js and forwards them to the service worker
- background.js - Routes messages to the appropriate DevTools panel by tab ID
- Frame Filtering Limitation - Why per-frame filtering isn't currently possible and technical background for contributors