Skip to content

Add debug-only component tree inspector#779

Open
AurelVU wants to merge 2 commits intoschultek:mainfrom
AurelVU:feature/devtools-inspector
Open

Add debug-only component tree inspector#779
AurelVU wants to merge 2 commits intoschultek:mainfrom
AurelVU:feature/devtools-inspector

Conversation

@AurelVU
Copy link

@AurelVU AurelVU commented Mar 17, 2026

Summary

Adds an interactive component tree inspector overlay for development builds, toggled with Ctrl+Shift+D. The inspector is fully gated behind kDebugMode and tree-shaken from release builds.

Features

  • Live component tree visualization with auto-refresh after each build cycle
  • Detail panel showing component type, depth, state fields, DOM attributes, and hydration status (SSR vs CSR)
  • Element picking with highlight overlay (click any element to find it in the tree)
  • Search/filter components by name
  • Source file navigation via DDC runtime metadata (VS Code, Cursor, IntelliJ IDEA, WebStorm)
  • Keyboard navigation (arrow keys, Enter, Escape)
  • Resizable panels with layout persisted in localStorage

Framework additions (debug-only)

  • Element.debugCreationStack / debugBuildOwnerElement — tracks which element's build() produced each child
  • RenderObject.debugWasHydrated — distinguishes server-rendered (hydrated) vs client-created DOM nodes
  • State.debugDescribeState() — opt-in hook for exposing state fields to the inspector
  • $jasprProjectInfo server endpoint — serves package path mappings for "Open in IDE" functionality

Files

File Purpose
devtools/tree_snapshot.dart Walks Element tree → serializable InspectorNode tree
devtools/inspector_panel.dart Pure DOM overlay panel with event delegation
devtools/inspector_highlight.dart Highlight overlay + browser DevTools inspect()
devtools/source_resolver.dart DDC metadata introspection for class→file mapping
devtools/inspector.dart Controller: keyboard shortcut, pick mode, post-frame lifecycle
test/devtools/tree_snapshot_test.dart 17 unit tests for tree snapshot logic

Versioning

CHANGELOG.md updated to Unreleased minor — this adds new debug-only API surface (debugDescribeState, debugWasHydrated, debugCreationStack, debugBuildOwnerElement).

Test plan

  • All 17 new devtools unit tests pass (dart test packages/jaspr/test/devtools/)
  • All 225 existing tests pass (dart test packages/jaspr/test/)
  • dart analyze clean on both jaspr and jaspr_cli packages
  • Manual: run a jaspr app in debug mode, press Ctrl+Shift+D, verify tree renders
  • Manual: verify pick mode highlights elements and selects in tree
  • Manual: verify "Open in IDE" resolves correct file paths
  • Manual: verify inspector is absent in release builds

Introduces an interactive overlay panel for visualizing the live component
tree during development. The inspector is fully gated behind kDebugMode
and tree-shaken from release builds.

Features:
- Live component tree with auto-refresh after each build cycle
- Detail panel showing type, depth, state fields, DOM attributes, hydration status
- Element picking with highlight overlay
- Search/filter by component name
- Source file navigation via DDC metadata (VS Code, Cursor, IntelliJ, WebStorm)
- Keyboard navigation (arrow keys, Enter)
- Resizable panels with persisted layout

Framework additions:
- Element.debugCreationStack / debugBuildOwnerElement for build-owner tracking
- RenderObject.debugWasHydrated for SSR vs CSR origin detection
- State.debugDescribeState() hook for exposing state to the inspector
- Debug-only $jasprProjectInfo server endpoint for package path resolution
@AurelVU AurelVU requested a review from schultek as a code owner March 17, 2026 12:48
@docs-page
Copy link

docs-page bot commented Mar 17, 2026

To view this pull requests documentation preview, visit the following URL:

docs.page/schultek/jaspr~779

Documentation is deployed and generated using docs.page.

@github-actions
Copy link

Package Version Report

The following packages have been updated:
jaspr_test : 0.22.3 -> 0.23.0
jaspr : 0.22.3 -> 0.23.0
jaspr_builder : 0.22.3 -> 0.23.0
jaspr_cli : 0.22.3 -> 0.23.0
jaspr_content : 0.5.0 -> 0.5.1
jaspr_lints : 0.6.0 -> 0.6.1
jaspr_router : 0.8.1 -> 0.8.2
jaspr_flutter_embed : 0.4.10 -> 0.4.11
jaspr_riverpod : 0.4.4 -> 0.4.5
jaspr_serverpod : 0.6.0 -> 0.6.1

@AurelVU
Copy link
Author

AurelVU commented Mar 17, 2026

Screenshots

1. Component Tree — SSR vs CSR origin badges

Full component tree showing server-rendered (green SSR) and client-rendered (orange CSR) nodes side by side. Stateful Counter component selected with live state fields (items: 3, count: 54) visible in the detail panel. Source file link and "Built by" relationship shown.

Tree with SSR/CSR badges

2. DOM Element Detail — Events, Source location, Inspect DOM

Selecting a <button> DomComponent shows: HTML tag, event count (1), source file link with "Open in IDE" button, "Inspect DOM" button for Chrome DevTools, and build-owner tracking. Blue highlight overlay marks the element on the page.

Button DOM detail

3. Component Search / Filter

Typing "Button" into the search bar filters the tree to show only matching components (highlighted in orange) and their ancestor chain. Non-matching nodes are hidden.

Search filter

4. Client-Rendered Element Detail

Selecting a client-rendered <li> element shows Origin: Client (dynamic) in the detail panel, confirming this node was created by client-side JavaScript rather than hydrated from server HTML.

CSR element detail


Screenshots from the package_riverpod example with dynamically-added list items to demonstrate mixed SSR/CSR content.

@schultek
Copy link
Owner

Wow thanks, that looks awesome. Let me try it out a bit and come back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants