Register custom DevTools panels from any web application — no overlays, no hacks.
🚧 This project is under active development. Expect rough edges, missing features, and breaking changes.
- Native DevTools panel — a custom Devtoolster tab alongside the built-in Chrome/Firefox DevTools
- Simple page-facing API —
@devtoolster/web-apilets any web app register controls viawindow.postMessage - Rich control types — buttons, text inputs, dropdowns, color pickers, toggles, sliders, and data tables
- Cross-browser — Chrome and Firefox, both built from a single WXT config
- Tab-based organisation — group registered controls into named tabs within the panel
- Node.js 18+ and npm / yarn
- Chrome 88+ or Firefox 109+ (Manifest V3)
npm installnpm run dev # Chrome
npm run dev:firefox # Firefoxnpm run build # -> extension/.output/chrome-mv3
npm run build:firefox # -> extension/.output/firefox-mv3npm run demo # serves http://localhost:8080Then open DevTools → Devtoolster tab.
In larger or enterprise web applications, development and QA often requires adjusting values or mocking state to demonstrate behaviour to stakeholders. Framework-provided tools are sometimes enough, but frequently cumbersome. Many teams end up writing their own dev tools — page overlays, query-parameter toggles, step-by-step guides bolted onto existing panels.
All of those approaches require effort that isn't always justified. Devtoolster aims to provide a slim, consistent API that lets any web application register custom controls inside the browser's native DevTools with minimal setup.
The extension is built with WXT (Vite-based) in TypeScript, with a Svelte-based DevTools panel. WXT generates the Chrome (service_worker) and Firefox (background.scripts) Manifest V3 files from a single config — no manual per-browser manifest swap. The page-facing API lives in @devtoolster/web-api, a TypeScript package built with Vite (library mode) and published through the same npm workspace.
- Typed TypeScript API (
@devtoolster/web-api) wrappingwindow.postMessage - Talks to the content script via window messaging
- Content script — injected into the page, bridges
windowmessaging to the extension runtime - Background worker — routes messages between the content script and the DevTools panel
- DevTools panel — registers the Devtoolster tab, listens for
devtools:open, and renders controls registered by the application
| Dark | Light |
|---|---|
![]() |
![]() |
| Dark | Light |
|---|---|
![]() |
![]() |
- No keyboard shortcuts or focus management
- No sorting or filtering for table data
- Stale panel content persists when navigating to a page without a matching content script (e.g.
chrome://,about:, or pages that don't inject the content script)
- Proper error handling and user-facing error states
- More UI controls (toggles, sliders, color pickers, …)
- Automated tests (e2e and unit)
- User approval prompt — per-session consent before the panel activates
I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the configuration
- Submitting a fix
- Proposing new features
- Becoming a maintainer
To get started please read the Contribution Guidelines.
- Node.js 18+
- npm
- Chrome or Firefox
After loading the extension and opening the demo page + DevTools panel:
- Tab bar shows two tabs: Table and Controls
- Clicking each tab switches the visible content
- The active tab has a highlighted bottom border
- Controls tab: Headings "Communication" and "Manipulate page" are visible
- Controls tab: "Hi from your todays host" button triggers an alert dialog
- Controls tab: "Log it baby one more time" logs to the page's console
- Controls tab: Dropdown "Select something" sends a selection event
- Controls tab: "Set random background" changes the page background color
- Controls tab: "Your name here" input submits the typed value
- Controls tab: Color picker "Overwrite background color" works
- Table tab: Table with columns Name/Age/City and 3 rows is visible
- Controls tab: "Cycle table data" button — switch to Table tab to see data change
- Controls tab: Unsupported element
{type: "test"}logs an error (expected) - Reloading the page (F5) resets and re-registers all controls under both tabs
- No "message port closed before a response was received" warnings in the background service-worker console (Chrome: inspect service worker from
chrome://extensions)




