You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Proposal: standalone browser extension support #329
I am building a Chrome extension that injects the @devframes/hub-ui embedded dock into an existing page.
In my setup, the inspected page and the Devframe server have independent lifecycles.
The inspected page keeps running when the local Devframe server stops. When the server restarts, I want to reconnect and remount the Devframe panel without reloading the inspected page.
Current gaps
This exposes three issues:
Embedded UI sizes using rem are affected by the host page's root font size.
Runtime Iconify requests may be blocked by the host page's CSP.
When the sidecar restarts, there is no public lifecycle API to dispose and remount the embedded Hub without reloading the inspected page.
Question
If this topology fits Devframe's intended scope, I would be happy to contribute improvements for these gaps, potentially including:
a browser extension example;
CSP-safe or configurable icon resolution;
stronger embedded style isolation;
explicit mount/dispose/reconnect lifecycle APIs.
I would appreciate guidance on the preferred API boundaries and how these changes should be split into separate issues or PRs.
I'd love to have this feature, this is something the ecosystem has been asking (to easily define the devtools and have the Browser extension available). I know that @webfansplz is working on this feature in Vite DevTools (vitejs/devtools#530). While I would love to have it in Devframe to have a wider audience for sure, I was thinking of having Alro explore the possibility with the codebase he is more familiar with. But if you want to try the approach from the Devframe side, that would also be greatly welcome. I just wish we could have a way to collaborate with each other, to share ideas and avoid duplicating efforts.
Thanks! I reviewed Vite DevTools, One distinction I noticed is that there are two different browser-extension topologies:
a Chrome DevTools panel or extension-owned viewer, as implemented in Vite DevTools;
an extension-injected viewer rendered directly inside the inspected page.
My current use case is the second one. That is why host-page rem, CSP, and sidecar restart lifecycle become visible. The Vite DevTools approach avoids most style and CSP problems by rendering the viewer inside an extension-owned iframe.
I’d be happy to explore how Devframe could support this second topology while reusing the extension work from Vite DevTools, rather than duplicating it.
I'd love to have this feature, this is something the ecosystem has been asking (to easily define the devtools and have the Browser extension available). I know that @webfansplz is working on this feature in Vite DevTools (vitejs/devtools#530). While I would love to have it in Devframe to have a wider audience for sure, I was thinking of having Alro explore the possibility with the codebase he is more familiar with. But if you want to try the approach from the Devframe side, that would also be greatly welcome. I just wish we could have a way to collaborate with each other, to share ideas and avoid duplicating efforts.
I think the three gaps can be split into separate PRs:
Style isolation — the embedded UI uses rem so it gets messed up by whatever root font size the host page sets
CSP-safe icons — Iconify makes runtime requests that the host page's CSP can block
Lifecycle API — mount/dispose/reconnect so you don't have to reload the page when the sidecar restarts
Adding a data point for the first topology this thread carved out, since it's slightly different from both #329 and vitejs/devtools#530.
I'm trying to surface Pinia Colada's devtools (@pinia/colada-devtools v2, which ships as a devframe) inside the Vue DevTools browser extension, so it sits next to the JS debugger, the network tab and the Vue inspector rather than in a separate UI. Vue DevTools lets any app contribute a panel with addCustomTab({ view: { type: 'iframe', src } }), so wiring it up is one line: point the iframe at the devframe the Vite hub mounts at <base><id>/.
It connects when the panel is inside the page, and never when it isn't. Tested against devframe 1.0.0:
Panel placement
Result
Vue DevTools overlay (iframe inside the app page)
connects, live data
window.open() from the app page
connects
Its own tab, same origin, app open elsewhere
stays connecting
Cross-origin parent (standing in for the extension)
stays connecting
The cause is defaultHandshakeTargets in the in-page channel: the panel posts hello to its ancestor chain plus those windows' openers, and the page script answers with a MessageChannel port. An extension panel is neither an ancestor nor an opener of the inspected page, so no hello ever arrives and no port is granted.
vitejs/devtools#530 gives Vite DevTools its own extension, with its own chrome.devtools.inspectedWindow relay. What's missing here is the complement — letting a devframe panel be hosted inside an extension panel someone else owns (here, vuejs/devtools). Any devframe embedded in any third-party devtools UI hits the same wall, so it can't be solved by each tool shipping an extension.
The channel itself already looks ready for it: connectPanelChannel takes transport?: MessagePort with window: false ("bypassing the handshake"), plus targets and instanceId, and the page-script side has addPanelPort.
(BroadcastChannel is tempting, since the panel iframe is same-origin with the app even when the extension hosts it, but storage partitioning keys it by top-level site, so it won't cross.)
Is "devframe panel hosted in a third-party extension panel" in scope for devframe, or is the intended answer "ship your own extension, as in #530"?
If it is in scope, would you prefer a documented WS-backed transport that adapts into connectPanelChannel({ transport }), or a different boundary?
Yes, this is exactly what I had in mind as well. Thanks everyone for the feedback—it’s really helpful as we think about web extension support in Devframe. Both Vite DevTools and Vue DevTools already have web extensions, so we need a unified approach to avoid duplicating the same work. I’ll start exploring how we can build this into Devframe.
Sounds good. Happy to help with the implementation once the approach is settled — especially the style isolation and lifecycle API parts I mentioned above. Let me know if there's a way to coordinate.
Activity
antfu commentedon Sep 2, 2026
I'd love to have this feature, this is something the ecosystem has been asking (to easily define the devtools and have the Browser extension available). I know that @webfansplz is working on this feature in Vite DevTools (vitejs/devtools#530). While I would love to have it in Devframe to have a wider audience for sure, I was thinking of having Alro explore the possibility with the codebase he is more familiar with. But if you want to try the approach from the Devframe side, that would also be greatly welcome. I just wish we could have a way to collaborate with each other, to share ideas and avoid duplicating efforts.
jinghaihan commentedon Sep 2, 2026
Thanks! I reviewed Vite DevTools, One distinction I noticed is that there are two different browser-extension topologies:
My current use case is the second one. That is why host-page
rem, CSP, and sidecar restart lifecycle become visible. The Vite DevTools approach avoids most style and CSP problems by rendering the viewer inside an extension-owned iframe.I’d be happy to explore how Devframe could support this second topology while reusing the extension work from Vite DevTools, rather than duplicating it.
clanzhang commentedon Sep 16, 2026
I think the three gaps can be split into separate PRs:
remso it gets messed up by whatever root font size the host page setsWhich one should I pick up first?
bperel commentedon Sep 17, 2026
Adding a data point for the first topology this thread carved out, since it's slightly different from both #329 and vitejs/devtools#530.
I'm trying to surface Pinia Colada's devtools (
@pinia/colada-devtoolsv2, which ships as a devframe) inside the Vue DevTools browser extension, so it sits next to the JS debugger, the network tab and the Vue inspector rather than in a separate UI. Vue DevTools lets any app contribute a panel withaddCustomTab({ view: { type: 'iframe', src } }), so wiring it up is one line: point the iframe at the devframe the Vite hub mounts at<base><id>/.It connects when the panel is inside the page, and never when it isn't. Tested against devframe 1.0.0:
window.open()from the app pageconnectingconnectingThe cause is
defaultHandshakeTargetsin the in-page channel: the panel postshelloto its ancestor chain plus those windows' openers, and the page script answers with aMessageChannelport. An extension panel is neither an ancestor nor an opener of the inspected page, so no hello ever arrives and no port is granted.vitejs/devtools#530 gives Vite DevTools its own extension, with its own
chrome.devtools.inspectedWindowrelay. What's missing here is the complement — letting a devframe panel be hosted inside an extension panel someone else owns (here, vuejs/devtools). Any devframe embedded in any third-party devtools UI hits the same wall, so it can't be solved by each tool shipping an extension.The channel itself already looks ready for it:
connectPanelChanneltakestransport?: MessagePortwithwindow: false("bypassing the handshake"), plustargetsandinstanceId, and the page-script side hasaddPanelPort.(BroadcastChannel is tempting, since the panel iframe is same-origin with the app even when the extension hosts it, but storage partitioning keys it by top-level site, so it won't cross.)
connectPanelChannel({ transport }), or a different boundary?webfansplz commentedon Sep 17, 2026
Yes, this is exactly what I had in mind as well. Thanks everyone for the feedback—it’s really helpful as we think about web extension support in Devframe. Both Vite DevTools and Vue DevTools already have web extensions, so we need a unified approach to avoid duplicating the same work. I’ll start exploring how we can build this into Devframe.
clanzhang commentedon Sep 17, 2026
Sounds good. Happy to help with the implementation once the approach is settled — especially the style isolation and lifecycle API parts I mentioned above. Let me know if there's a way to coordinate.