Browser DevTools for inspecting and debugging Web Components — the component-level view that Vue DevTools and React DevTools give their frameworks, for Lit, FAST, Stencil and vanilla custom elements.
| Elements panel | WC DevTools | |
|---|---|---|
| Component tree (only custom elements, shadow DOM pierced) | ❌ mixed with every div | ✅ |
| JS properties (not just attributes) | ❌ | ✅ live-editable |
adoptedStyleSheets |
❌ invisible | ✅ with CSS viewer |
Exposed ::parts + rules targeting them |
❌ | ✅ |
ElementInternals custom states (:state()) |
❌ | ✅ toggleable |
| Events per component | ❌ | ✅ log + dispatch |
| Invoke component methods | console only | ✅ one click |
| Re-render profiling / trace updates | ❌ | ✅ |
| Click-to-source on the component class | ❌ | ✅ |
| CEM documentation in place | ❌ | ✅ + auto-fetch |
- Component tree — full hierarchy of custom elements, shadow DOM included, virtualised (comfortable on 5000+ elements), with iframe support (Storybook works)
- Live editing — properties, attributes and CSS custom properties, editable in place; reset to first-seen value per row
- Methods — list user-defined methods and invoke them with JSON arguments, result inline (Promises awaited)
- Events — real-time
CustomEventlog per component, plus dispatch your own events from the panel - Click-to-source — jump to the file that registered the component, source maps applied (
srcbutton) - Trace updates — flash components on the page as they re-render (toolbar toggle)
- Re-render profiling — top components by update frequency over a rolling window (Perf tab)
- Picker — click a component on the page to select it in the tree
- Console bridge — the selected component is
$wc/$wc0in the console ($wc1..$wc4keep history) - Framework detection — Lit (with version), FAST, Stencil (with SSR/hydration badges), vanilla
These exist only in Web Components — no other devtools shows them:
- Slots — assigned vs fallback nodes per
<slot>, plus how many::slottedrules target the host's shadow root. ::partexposures — every part exposed inside a shadow tree, with the count of CSS rules currently targeting it.- adoptedStyleSheets — constructible stylesheets applied to a shadow root (invisible in the browser's Elements panel), in a CodeMirror CSS viewer.
- CSS custom properties — variables resolving on the host with computed values and host/inherited origin — editable live, the design-system theming workflow.
- CustomStateSet — active states from
ElementInternals.states(:--loading,:--ready…), with click-to-remove chips. - Cross-root ARIA —
aria-controls,aria-describedbyetc., flagged when the target lives in a different (shadow) root than the source. @statevs@propertydistinction — internal state and public properties visually badged (LitelementProperties, StencilcmpMeta$).- Lit Labs integration — Signals tab for
@lit-labs/signalsvalues,@lit/contextrequest keys, and@lit/taskstatus. - Custom Elements Manifest — loads your project's
custom-elements.json, and auto-fetches the manifest of known design systems (Shoelace, Web Awesome, Vaadin, UI5, Lion) for instant docs on the CEM tab. - Stencil hydration badges — tell SSR-only nodes from hydrated ones at a glance.
Requirements: Bun ≥ 1.2
git clone https://github.com/jpinhel/wc-devtools.git
cd wc-devtools
bun install
bun run buildThen load the unpacked extension from .output/chrome-mv3 in chrome://extensions (enable Developer mode first).
bun run devWXT will auto-reload the extension on file changes.
bun run build && bun run playground # → http://localhost:5180Runs the real built panel against a demo page in a plain browser tab (no
extension involved) — the extension's message protocol bridged by
playground/harness.js. Used as a reproducible manual-testing target and to
record the README GIF (bun playground/record-demo.ts).
- Open DevTools on any page (
F12) - Go to the Web Components tab
- The component tree appears automatically
- Click a node to inspect its properties, attributes, methods, and events
- Click a property value to edit it live — booleans toggle on click
entrypoints/
background.ts — MV3 service worker, message routing, badge
content.ts — bridge between page context and extension bus
wc-inspector.ts — injected into page (world: MAIN), reads the DOM
panel/ — DevTools panel (Lit)
devtools.ts — registers the DevTools panel
popup/ — toolbar popup
lib/
inspector-core.ts — pure tree-building and serialization logic
types/
wc.ts — shared types and message protocol
Message flow:
wc-inspector (page)
│ window.postMessage
▼
content.ts
│ chrome.runtime.sendMessage
▼
background.ts
│ port.postMessage
▼
DevTools panel (Lit)
| Tool | Role |
|---|---|
| WXT | Extension framework (MV3) |
| Lit | DevTools panel UI (the panel dogfoods Web Components) |
| Biome | Linter + formatter |
| Vitest | Unit tests |
| Bun | Package manager + runtime |
| Command | Description |
|---|---|
bun run dev |
Development build with auto-reload |
bun run build |
Production build |
bun run zip |
Packaged extension ZIP |
bun run test |
Run unit tests |
bun run lint |
Lint with Biome |
bun run lint:fix |
Lint + auto-fix |
bun run compile |
TypeScript type-check |
Pull requests are welcome. For significant changes, open an issue first to discuss the approach.
bun run lint # must pass
bun run test # must pass
bun run compile # must pass