Reaktor DevTools

DevTools is the workbench pane that shows what a running app is doing on real phones. It mirrors each phone live, side by side, and lets you inspect the app, drive it from the desktop, scroll back through what the screen showed, and score it the way Lighthouse scores a web page.

Status: rebuilt end to end and checked on a Samsung Galaxy S23 (Android 16) and an iPhone 14 Pro (iOS 26.5) on 30 September 2026. Sections 1–5 describe what ships. Section 6 compares it with the tools it learns from, section 7 is the roadmap, and section 8 keeps the design direction the earlier version of this page set out.

The DevTools pane with the Galaxy and the iPhone mirrored side by side. The selected button is outlined on the Galaxy and its match is dashed on the iPhone.

At a glance

  • Screens. Each phone is mirrored live. Inspect mode picks elements; Interact mode taps, drags, scrolls and types into the real app.
  • Elements. The app's real UI tree from each phone, matched across the two phones, with accessibility checks.
  • Network. Every HTTP call with headers, bodies and timing, and every WebSocket connection with its messages. Filter with a query language, export HAR, slow the app's network down, take it offline, or block a request.
  • Logs. App logs, plus the system log on Android, with the same query language.
  • Timeline. Frames, network, graph ports, logs and memory on one clock, with a filmstrip of the screen. Click or drag the filmstrip and the phone mirror shows that moment again.
  • Audits. Live scores for performance, network, accessibility, stability and parity between the phones, each finding linked to the request, log line or element behind it.
  • Graph. Call counts, failures and latency per port of the app's dataflow graph.
  • Device. Launch, stop and restart the app, launch time, deep links, display settings, network conditions, the app's own commands, and crashes.
  • Saved sessions. Save what the pane captured from a phone to a .reaktortrace file, open it later without the phone, and compare it side by side with a live phone.
  • Coding agents. Seven read-only MCP tools give an agent the same devices, audits, requests, logs, elements and sockets.

Operations and Shadow integration

DevTools belongs to Operations & Reliability. Its live-device frame, memory, startup, traffic and port observations complement Crashlytics and Reaktor client evidence and instance diagnosis. The Measure tab, SDK wrappers, dashboard client, interceptor and local launcher are removed. Reaktor application-session IDs carry client identity. Hangar Telemetry has separate kernel-owned backend span and Crashlytics report reads; neither needs an attached phone. Provider readback and exact graph attribution remain qualification work.

DevTools is gated to debug builds. Current BestBuds debug capture includes request/response bodies and WebSocket text with pattern masking; this is development-only evidence, not a production privacy guarantee. Release qualification must prove debug DevTools capture is absent and the resolved mobile artifacts contain no Measure SDK. Crashlytics and ordinary Reaktor client evidence contain no payload bodies. Any future payload journal follows Shadow privacy and effect safety.

For deeper CPU/heap/native diagnosis use Profiling. Recorded interactions become Shadow inputs only with pinned client/backend state, artifact identity, approved effects and fixed assertions; a screen timeline or network transcript alone does not reconstruct a complete execution. Client verification owns that contract. Keep measured instance footprint distinct from app download/installed size and confirmed retained-object leaks.

1. How it works

Three independent paths feed the workbench:

  • Live device inspection: a debug app embeds Reaktor's DevToolsAgent. Screens, semantics, logs, network observations, vitals and graph facts travel over the device connection to Hangar. This powers the core DevTools panes.
  • Backend service evidence: a bounded ClickHouse read runs through the kernel execution ledger. KernelTelemetryNode supplies the same environment-scoped retained receipt to Hangar's backend Spans view, system overlay and read-only telemetry_spans MCP tool. Missing session/build/node/digest columns, unresolved parents, stale receipts and limits remain explicit. Overlay placement by service contract is inferred; exact revision-qualified graph attribution remains unfinished.
  • Mobile crash reports: KernelCrashesNode calls the existing Firebase provider through the trusted workspace door. Hangar's Crashes pane and telemetry_crashes read its retained report and provenance. The initial report covers up to 50 issues over seven days, with separate Android/iOS reads. Firebase app registrations currently combine dev and production, so reports are partial evidence. CLI sign-in and provider readback remain required.

Measure previously supplied an additional SDK and dashboard tab. It did not power the core device transport or DevTools agent.

The app carries a small agent, reaktor-devtools, that streams what it sees and accepts commands. The desktop reaches it over one socket per phone:

Android   app agent ── localabstract:reaktor-devtools ── adb forward ─────────┐
iOS       app agent ── loopback port 47821 ─────────── idb_companion --forward ┤── DevTools pane
                                                                               ┘   (engine · devices)

The agent is only in debug builds that ask for it. BestBuds turns it on with the Gradle property bestbuds.devTools=true. An agent serves one connection at a time, so the pane only connects to the phones you have chosen; a phone another tool is using is left alone.

What the agent sends, and where each part comes from on each platform:

CapabilityWhat it carriesAndroidiOS
screenJPEG frames (up to 1280 px, up to 8 per second) with the whole UI tree taken at the same momenta graphics layer over the app root, and Compose's semantics treethe same layer, and the UIKit accessibility tree that Compose Multiplatform builds
trafficHTTP calls with headers, bodies up to 64 KiB and timing; WebSocket connections, their messages (text up to 16 KiB) and how they closed; secrets are maskeda plugin in reaktor-io's Ktor client, and a hook in its WebSocket clientthe same
logsthe app's logs; on Android also the system log for the app's processagent log sink, logcat over adbagent log sink
port.eventscalls crossing the app's graph ports, with duration and failuresgraph tapsgraph taps
graph.shapethe app's whole graph (scopes, nodes, ports, wires, routes, back stacks), sent again when navigation changes it; read by the Graph paneGraph.shapes()Graph.shapes()
port.watchon request, the result of each call through a watched port, summarised and masked; only on builds that capture valuesgraph tapsgraph taps
vitals.frameeach frame's duration against the display's own frame intervalChoreographerCADisplayLink
vitals.memorymemory in use, sampledruntimetask info
vitals.startuptime from process start to the first drawn frameProcess.getStartUptimeMillis()process start time from sysctl
crashcrashes, kept on disk and sent on the next connectioncrash hookcrash hook
inputtap, drag, scroll, type, keys, Backtouch events and semantics actions; Back through adbaccessibility actions and the text-input responder; Back through Compose's back dispatcher
faultnetwork conditions: extra latency, a failure rate, offline, blocked URL patternsreaktor-io HTTP conditionsthe same

A few rules keep this safe on a phone someone is using:

  • Actions that change or remove data on the device, such as clearing app data or uninstalling, go through the workbench's approval step. Taps, typing and scrolling go straight through.
  • When network conditions are on, the phone's header in the pane shows a badge. Clicking the badge turns them off. They also end when the app restarts.
  • Request headers that look like secrets, and secret-looking values in bodies and logs, are masked in the agent before they leave the phone.
  • The agent must never take the app down. A failure inside it, such as the desktop's connection dropping mid-message, is written to the app's log as a warning and the agent carries on.
  • The agent keeps listening. If its socket stops working, it opens a new one. On iOS it also opens a new one each time the app comes back to the foreground, because iOS can take a listening socket away from a suspended app.
  • The screen is read without racing the app. On iOS the agent records the frame's drawing commands on the main thread, which is cheap, and turns them into pixels on a background thread.

The desktop half lives in bestbuds/modules/engine/.../workbench/devices: DevToolsState finds devices and holds the selection, one DeviceLink per phone holds that phone's data, and each tab is one file.

2. The pane, tab by tab

Screens

  • Inspect highlights the element under the pointer and selects it on click. When two phones are shown, the matching element on the other phone gets a dashed outline.
  • Interact sends taps, drags, scrolls and typing to the real app. Back and Home are in each phone's header.
  • Outlines draws every element's bounds. Mirror taps repeats a tap on the matching element of the other phone.
  • Record turns what you do in Interact mode into a Maestro flow you can copy or save.
  • A small readout on each screen shows the share of slow frames in the last ten seconds and the memory in use.

Elements

  • The tree comes from the phone itself: Compose semantics on Android, the UIKit accessibility tree on iOS. Elements with a testTag carry the same id on both.
  • Parity counts how many elements match on the other phone and lists the ones found on only one. Only differences hides the rest.
  • Accessibility issues marks tappable elements with no label, touch targets under 48 dp (Android) or 44 pt (iOS), and repeated test tags.
  • The details panel can tap, focus, set text or copy a Maestro step for the selected element.

Network

A failing analytics request selected in Network, with its headers, JSON body and response in the details panel.

  • One row per request: status, method, path and host, type, size, time, a waterfall, and the graph port that caused it when the call went through a typed port.
  • The details panel shows headers, pretty-printed bodies, Copy as cURL, and See the screen at this moment, which jumps the phone mirror to when the request started.
  • The download button saves the visible requests as a HAR file, which Chrome DevTools and Charles can open.
  • Block requests like this in a row's menu makes the app's matching requests fail until you unblock them in the Device tab.
  • Sockets, the switch above the table, lists the app's WebSocket connections: status, URL, messages sent and received, bytes, and how long each was open. Selecting one shows its messages in order, each with its direction, time since the connection opened and size, and JSON pretty-printed. Heartbeat pings and pongs are hidden unless you ask for them.
  • A socket that failed to open, or closed with a code other than 1000 (normal closure), is marked red. It also gets a mark on the Timeline's Sockets lane and counts against the Network audit.

The filter box takes a small query language, copied from Logcat and Chrome:

QueryMatches
analyticstext anywhere in the method, URL, status or operation
-analyticsleaves those out
~^/v2/a regular expression
method:POST · status:401 · status:4xx · status:failedmethod and status
host:edge · path:/circles · cause:userRepositoryparts of the request, and the port that made it
is:failed · is:slowfailed, or over one second
age:30s · larger-than:100k · slower-than:2stime since, response size, duration

Logs take tag:, message:, level:warn (that level and above), is:error, is:crash, is:app, is:system and age: in the same way.

Timeline and replay

The Timeline with the Screens filmstrip. The playhead is at 3.5 seconds ago, and the Galaxy's mirror shows the screen from that moment.

  • One clock for frames, network requests, graph port calls, logs and memory, over the last 10 seconds, 30 seconds, 2 minutes or the whole session.
  • Screens is a filmstrip of what the phone showed. Click it, or drag along it, and the phone's mirror shows that moment with the UI tree from that moment. Elements and the details panel follow. The arrow keys step one frame; Escape or Back to live returns.
  • Dragging across the other lanes narrows Network and Logs to that stretch of time.
  • Clicking a request, a port call or a log line in a lane selects it.

The pane keeps up to 240 screens per phone, one every 400 ms at most, so about the last two minutes of activity, and only while the pane is connected.

Audits

Audits for both phones side by side: score rings per category, a metrics table, and findings.

  • A score from 0 to 100 per category and per phone: Performance, Network, Accessibility, Stability, and Parity when two phones are shown. Section 3 explains the scoring.
  • The metrics table puts both phones next to each other with the target for each metric.
  • Findings are sorted by how serious they are. Clicking one selects the request, log line or element behind it and opens the right tab; clicking again steps to the next piece of evidence.
  • The scores cover the last two minutes or the whole session, and update every two seconds.

Graph

  • The app's graph nodes and their ports, with calls, failures, median and worst latency, and a sparkline per port. Selecting a port can reveal its node in the workbench's Graph mode.

Device

The Device tab with the Galaxy slowed by 800 ms. The phone's header shows the +800 ms badge.

  • The device and the app: model, OS, connection, build, and Launch, the time from process start to the first drawn frame on the last cold start.
  • Launch, Stop and Restart. Clear data and Uninstall go through approval.
  • Open a deep link.
  • Dark mode and text size on Android. These change the whole phone.
  • Network conditions: Normal, Slow (+800 ms), Very slow (+2.5 s), Flaky (30% of requests fail) and Offline, plus the list of blocked patterns. They change the app's own HTTP requests, including new socket connections.
  • App commands: anything the app registered with its agent, such as log level, overrides and navigation.
  • Crashes, with their stack traces in the details panel.

The Desktop preview chip in the device bar opens the in-process preview and graph inspection workspace built on 13 September, for apps running inside the desktop JVM.

Saved sessions

  • Save in a phone's header writes everything the pane holds for that phone to a .reaktortrace file on the Desktop: screens and UI trees, requests, sockets, logs, graph port calls, frames, memory, crashes, the launch time and the network conditions.
  • Open a saved session (the folder button in the device bar) adds the recording as a phone of its own, marked Saved. Every tab works on it with the clock stopped at the moment it was saved, including replay, audits, filters and HAR export.
  • A session opened while one phone is shown appears next to it, so a live phone can be compared with a recording, or an Android run with an iPhone run from earlier.
  • A saved session refuses taps, Back and other commands, because there is no app behind it.
  • The file is a zip: manifest.json (format reaktortrace/1, the device, the app build, launch time and network conditions), data.json (everything else) and screens/NNNN.jpg.

For coding agents

Reaktor Desktop's MCP server (127.0.0.1:8765) carries seven DevTools tools. They read what the pane has captured. If the DevTools mode has not been opened in that window, the first read starts device discovery and attaches to the connected phones.

ToolReturns
devtools_devicesthe phones and saved sessions, with the app, its build, launch time, counts of requests, sockets and logs, and any network conditions
devtools_auditscores, metrics and findings with their evidence, for the last two minutes or the whole session
devtools_requestsrequests newest first, filtered with the same query language as the Network tab
devtools_requestone request in full: headers, bodies up to 16 KiB with secrets masked, and a cURL command
devtools_logslog lines, filtered with the Logs query language
devtools_elementsthe elements on screen now, with bounds, actions and accessibility issues
devtools_socketsWebSocket connections, and one connection's messages

A phone is named by its device key, part of its name, android or ios. The tools only read; driving a phone stays in the pane.

3. How the audit scores work

Each metric is scored on the same curve Lighthouse uses. A metric has two control points: a good value that scores 90 and a median value that scores 50. Between and beyond them the score follows a log-normal curve, so improving a bad value moves the score a lot and polishing a good one moves it a little. Pass/fail checks score 100 or 0. A category's score is the weighted average of its metrics. Rings are green from 90, orange from 50 and red below.

CategoryMetricGood (90)Median (50)WeightWhere the numbers come from
PerformanceLaunch to first frame, Android1.5 s5 s20Android vitals calls a cold start of 5 s or more slow
PerformanceLaunch to first frame, iOS400 ms2 s20Apple's goal is a first frame within 400 ms
PerformanceSlow frames (over 1.5× the frame interval)5%25%25Android vitals flags sessions with over 50% slow frames
PerformanceFrozen frames (over 700 ms)0.01%0.1%20Android vitals flags over 0.1% frozen
PerformanceHitch time, ms late per second102525Apple: up to 10 good, up to 25 warning, over 50 critical
PerformanceMemory growth per minute2 MB12 MB10Reaktor's own choice
NetworkFailed requests1%10%30Reaktor's own choice
NetworkResponse time p95500 ms1.5 s25Reaktor's own choice
NetworkLargest response256 KB1 MB10Reaktor's own choice
NetworkRequests on a timernone—20pass/fail
NetworkFailing on repeat (3 or more in a row)none—15pass/fail
AccessibilityTappable elements have labelsall—10pass/fail; weights follow Lighthouse's critical, serious and moderate
AccessibilityTouch targets are large enoughall—748 dp on Android, 44 pt on iOS
AccessibilityTest tags are uniqueall—3pass/fail
StabilityCrashesnone—10pass/fail
StabilityHangsnone—5Android 5 s (an ANR), iOS 500 ms (Apple's hang)
StabilityError log lines per minute0.555Reaktor's own choice
ParityElements missing on the other phone5%30%10Reaktor's own choice

The findings that go with the scores:

  • Performance: slow launch, a high share of slow frames, frozen frames, frames running late, memory growing steadily.
  • Network: the same endpoint called on a steady timer, an endpoint failing again and again, requests over a second, responses over 512 KB, the same request sent twice within 300 ms.
  • Accessibility: unlabelled controls, small targets, repeated test tags. These check the screen shown now, the way Lighthouse checks one page.
  • Stability: each crash, hangs, and a burst of error log lines.
  • Parity: elements on one phone with no match on the other. This only means something when both phones are on the same screen.

The curve and its clamps are Lighthouse's own: the score is (1 − erf(x)) / 2 with x = ln(value / median) × 0.906 / ln(median / good), clamped to 90–100 below the good value, 50–89 up to the median and 0–49 beyond it, with Lighthouse's small bonus above 90.

4. Checked on real phones

On a Galaxy S23 and an iPhone 14 Pro running a BestBuds debug build, 30 September 2026:

  • Both phones mirrored live together: 74 UI nodes on the Galaxy and 43 on the iPhone, with the same test tags on both.
  • From the desktop: taps, scrolling and typing on both phones; set text by element id on the iPhone; Back on the Galaxy and in the iPhone's dialogs.
  • Launch to first frame: 1.30 s on the Galaxy, about 0.2–0.3 s on the iPhone.
  • Offline mode made the app's next analytics requests fail with Offline: set from Reaktor DevTools; Normal restored them. The desktop set +800 ms on the Galaxy and read it back.
  • The audit found real problems in BestBuds:
    • While signed out, POST /analytics/events fails with 401 again and again: 12 times in a row in two minutes on the Galaxy, and three times in 22 seconds while offline.
    • The iPhone has three tappable elements with no label.
    • The developer sign-in buttons on the Galaxy are 46 dp tall, under the 48 dp minimum.
  • Replay: after a scroll, the Timeline's filmstrip brought back the scrolled screen on the Galaxy's mirror while the iPhone stayed live.
  • The pane's render test runs against both phones and saves every tab, replay and network conditions as images, with no Compose runtime errors. The routing, inspection, shell and every-pane tests pass.

A third pass the same day found three agent bugs on the iPhone and fixed them:

  • After the app went to the background and came back, the agent stopped accepting the desktop. It now listens again with a backoff, and re-binds when the app returns to the foreground.
  • Reading the screen off the main thread crashed the app. The frame is now recorded on the main thread and turned into pixels off it.
  • An error inside the agent could stop it. It is now logged and the agent carries on.

Two tests cover the first and third: the listener dies and comes back, and a failure inside the agent is logged instead of thrown. Back on iOS now uses Compose's own back handling; a Maestro flow swipes back from the screen edge on an iOS 26.5 simulator and passes. Back on Android now goes through the activity's back dispatcher; that is built but not yet tried on the Galaxy.

5. Known limits

  • A locked iPhone. iOS pauses the app while the phone is locked, so its agent stops answering. The pane asks you to unlock the phone and connects again once the app is back in front.
  • Replay covers screens and UI trees only, for about the last two minutes. Graph state at the playhead is not recorded yet.
  • Launch time is time to the first frame. Time until the screen is fully drawn needs the app to say when it is ready.
  • Sockets show text messages up to 16 KiB. Binary messages show only their size.
  • One iOS simulator at a time. Every simulator shares the Mac's loopback. When two simulators run an app with the agent, only the first agent gets port 47821, and the pane shows that app for both simulators.
  • Hitch time counts every frame, including idle ones. Apple measures it during scrolling and animation, so an idle app reads better here than it would in Xcode.
  • No profiler yet. There is no CPU sampling or heap analysis.
  • Accessibility checks labels, sizes and tags. It does not check contrast, clipped text or large text sizes yet.

6. How it compares

The comparison covered Chrome DevTools and Lighthouse; Android Studio, Xcode and Instruments; VS Code; Flutter and React Native DevTools; Unreal Engine's Insights, Rewind Debugger, Visual Logger and Gameplay Debugger; and measure.sh, with Perfetto, Macrobenchmark, Flashlight and Sentry for performance numbers.

CapabilityWho does it bestReaktor today
Live mirror of a real phone with inspection on topAndroid Studio's Running Devices with Layout Inspector; Xcode 27 Device HubYes, Android and iPhone side by side
The running app's UI treeChrome Elements; Layout Inspector; Xcode View Debugger; Flutter InspectorYes. No 3D view yet
Both platforms compared element by elementnone of themYes: matches, "only here", the counterpart outline
Network capture with bodiesChrome Network; Studio Network Inspector; Instruments HTTP TrafficYes, HTTP and WebSocket. The issuing port is shown when known
Network throttling, offline and blockingChrome network and request conditionsYes, from inside the app, with no proxy
A filter languageLogcat queries; Chrome filtersYes
HAR filesChromeExport. No import yet
Many lanes on one clockChrome Performance; Unreal Timing Insights; PerfettoYes, with brushing
Going back in timeUnreal Rewind Debugger; measure.sh session replay; Chrome's filmstripScreens and UI trees. Graph state not yet
Scored auditsLighthouse; FlashlightYes, five categories, live
Launch timeMacrobenchmark; Xcode OrganizerTime to first frame. Not time to fully drawn
Jank, hitches and hangs by the vendors' own rulesStudio janky frames; Instruments; Flutter frame chartYes
Why something updatedStudio recomposition counts; SwiftUI Cause & Effect; React; Unreal Slate InsightsNot yet
Memory profilingChrome heap snapshots; Studio heap dumps; Xcode Memory Graph; Unreal Memory InsightsNot yet
Recording a flowChrome Recorder; Maestro StudioRecords Maestro flows. No replay or measuring yet
Saving a session to open laterUnreal .utrace; Chrome traces; Playwright tracesYes, .reaktortrace, opened next to a live phone
An agent driving the toolChrome DevTools MCP serverSeven read-only DevTools tools over MCP. No driving yet

What each tool taught, in one line:

  • Chrome: one selection that every panel follows, one time axis that filters every table, and a saved file that reopens with its links intact.
  • Lighthouse: score each metric on a curve between a good and a median value, and link every finding to the node or request behind it.
  • Android Studio and Xcode: inspect on top of the live phone, and judge performance by the platform's own definitions of slow, frozen, hitch and hang.
  • VS Code: a debug protocol with capabilities agreed at the start, and logpoints that log without stopping the program.
  • Flutter and React Native: tap on the device to select, per-frame bars coloured by the part that missed its deadline, and "why did this render".
  • Unreal: record everything cheaply on one clock, then scrub it; overlays per object on the running game; saved sessions you can compare.
  • measure.sh: a session timeline that plays back the screen, launch times split into cold, warm and hot, and endpoints grouped into patterns.

7. Roadmap

Ordered by how much each area adds. ✅ done, ⬜ still to do.

1. Cause and effect. Only Reaktor can do this, because it owns the graph.

  • ⬜ Link each tap to the port it fired, the requests that followed, the state it changed, the recomposition and the frame.
  • ⬜ Show which port issued every request.
  • ⬜ Count recompositions per element and say which input changed.

2. Time.

  • ✅ Replay screens and UI trees from the Timeline, and jump there from a request or a log line.
  • ⬜ Record graph state changes so the playhead shows port values as well.
  • ⬜ Bookmarks and named regions, placed from code or from the pane.
  • ✅ Save a session to a .reaktortrace file, open it later without the phone, and compare it with a live phone or another session.

3. Performance.

  • ✅ Launch to first frame; slow, frozen and late frames; hangs; the on-screen readout.
  • ⬜ Time to fully drawn, from a graph "ready" port so both platforms measure the same moment.
  • ⬜ Tag each frame with the screen and graph node on top, so findings can say where.
  • ⬜ Export a session to Perfetto for deep Android traces.

4. Network.

  • ✅ Capture with bodies, HAR export, network conditions, blocking, the query language.
  • ✅ WebSocket connections and messages, which BestBuds uses for chat and circles.
  • ⬜ Rules that rewrite a response's status, headers or body.
  • ⬜ Resend a request, with or without edits.

5. Audits.

  • ✅ Live scores and linked findings for five categories.
  • ⬜ Run a recorded Maestro flow several times on both phones and score the run, as Lighthouse user flows and Flashlight do.
  • ⬜ Contrast, clipped text and large-text checks.
  • ⬜ Flag a regression against the previous run.

6. Memory.

  • ⬜ Heap dumps on Android, analysed on the desktop. iOS stays unavailable.

7. Agents.

  • ✅ Give coding agents the same reads through MCP: devices, audits, requests, logs, elements and sockets.
  • ⬜ The screen image over MCP, and driving the phone (tap, type, Back) through the workbench's approval step.

8. Platform gaps.

  • ✅ Back on iPhone graph screens: reaktor-graph now uses Compose's back handling, with the interactive edge swipe.
  • ⬜ Long press on iOS.
  • ⬜ A command menu for every action in the pane.

8. Design direction

The earlier version of this page, from 13 September 2026, designed DevTools as the place to ask what produces this pixel, what did it do, and what breaks if I change it. Its rules still hold for the next steps. The full text is in the page's git history.

  • One selection travels. Every panel reads and writes one selected subject: an element, graph node, port, connection, route, request or log line. The workbench keeps it in WorkbenchInspectionSession in the kernel, so the shell and the MCP host read the same thing. Answers that arrive after the selection has changed are dropped.
  • From an element to the graph. An element names the control it is, through Modifier.reaktorElement, and a binding says which graph node, handler and port own it. Finding a binding does not prove the handler ran. Several possible owners are shown as ambiguous and never picked at random.
  • Routes, drawn pin to pin. A control starts one or more routes through the graph. The useful view draws a chosen route end to end through folded scopes, with returns, errors and retries in their own colour, and marks what the graph cannot see.
  • The reverse direction. From a state or service change, show the UI it affects. Showing where a component is mounted is simpler than working out everything a change affects, and the two are labelled differently.

The investigation model

DevTools is organised around one investigation: what is selected, where it runs (which phone or server), when (live, a moment, or a range), and what we know about it (declared in code, observed, recorded or unknown). Two selections apply everywhere: the subject, and the time range. Brushing a time range narrows every surface at once; the Timeline's replay is the first part of that.

  • Changes to the running app, such as network conditions, overrides or recorder playback, are visible while they are on and can be turned off from where they show.
  • A saved session (.reaktortrace) is a bundle of evidence: screens, trees, requests, logs, graph events and the findings, openable without the app. The first version records and shows; it does not promise to replay the app deterministically.
  • Agents get the investigation itself: the subject, the time range, the evidence and what is missing.

Sources for the comparison: Chrome DevTools and its MCP server; Lighthouse performance scoring; Android Studio's Layout Inspector, jank detection and Logcat; Android vitals on rendering, launch time and ANRs; Apple on hangs, hitches and launch time; VS Code debugging; Flutter DevTools; React Native DevTools; Unreal Engine's Insights and Rewind Debugger; measure.sh; and Flashlight.