Beyond the panel
Share & automate
What BevTools records can leave the in-app panel: into a window of its own, into the browser's DevTools, into a file a colleague opens, and into CI. Every one of them reads the same data through the same redaction, so none shows more than the panel does.
Three frontends, one protocol
In each .NET runtime BevTools records what happens and answers questions about it (BevToolsProtocol).
A script on the page, the page hub, keeps one target per runtime that rendered a
<BevToolsPanel /> - a Blazor Server circuit and the WebAssembly runtime can share a page - and
three frontends read it:
| Frontend | Where | What it is best at |
|---|---|---|
| In-app panel | Inside the app, on every host: Server, WebAssembly, Auto, Blazor Hybrid | Live object inspection, the profiler's batch views, panels that extensions contribute, nothing to install |
| Companion window | ⧉ in the panel header: a window of its own, same origin | Every runtime of the page at once; renders nothing into the app, so on Blazor Server it adds no render batches to the circuit it measures; opens exported sessions offline |
| Browser extension | A Blazor panel in Chromium or Firefox DevTools | The companion where developers already look; follows the Elements panel's selection (Chromium); no permissions, no content script |
Ask the page hub does what the companion and the extension do: it lists the targets with
window.__BIT_BEVTOOLS__.targets() and asks each one hello. The link opens the companion
the way ⧉ does; a runtime appears in it once its panel has rendered. Set Ui.ShowBadge = false to
keep the in-app panel out of sight and use only the companion or the extension.
Share what you found
About exports the session three ways, the same as >export, >report
and >trace in CtrlK:
- Export session (JSON): everything the panels show, in the
bit-bevtools/1format. The companion opens it offline (Open file, or drop it on the window), Profiler → Compare… compares against it, andbevtoolschecks it in CI. - Copy report (Markdown): the findings, the errors and their groups, the busiest endpoints and the costliest components, ready for an issue.
- Export performance trace: the timeline in the Chrome Trace Event format, which ui.perfetto.dev and the Chrome DevTools Performance panel open as they are - render batches with each component's render nested inside, UI events, navigations, requests and interop calls on tracks of their own, and arrows from each event to what it caused. Export performance trace since the profiler baseline in the palette keeps only what happened after the last Reset.
Each contains exactly what the panels show, with the same redaction; browser storage previews are left out. To
keep a busy app from pushing what you are reading out of the buffers first, pause capture (⏸ Pause in the
header, or >pause): errors are still collected, and the resume marker says how many renders were
skipped.
The browser extension
# from src/Utilities/BevTools dotnet build Bit.BevTools # builds the companion bundle the extension hosts cd Bit.BevTools.Extension && node build.mjs # assembles the unpacked extension in dist/
Load dist/ unpacked (chrome://extensions → Developer mode → Load
unpacked, or Firefox's about:debugging → Load Temporary Add-on), open DevTools on this
site and pick the Blazor panel. It reaches the page only through DevTools while DevTools is open
on the tab.
Compare two recordings
Profiler → Compare… reads an export from before a change and compares each component type with what has rendered since: regressed, improved, new or gone, with its renders and time before and after, warnings when the two recordings differ in how they were made, and Copy as Markdown. Render counts are compared exactly; times only beyond 5 ms and 50 %, because they vary between runs. The Products page has a fix to measure this way.
Fail a build on what BevTools found
The bevtools .NET tool (Bit.BevTools.Cli) reads export files - never a running app -
writes Markdown and exits with 1 when the check fails (2 when an input cannot be read):
dotnet tool install --global Bit.BevTools.Cli # the rules' findings: warnings and errors fail by default bevtools check checkout.session.json --fail-on warning --ignore render.storm --report "$GITHUB_STEP_SUMMARY" # a component type that renders more often, or clearly longer, than in the baseline bevtools compare checkout.baseline.json checkout.session.json
Most rules look back 10 to 60 seconds when they run, so for a recording you will check, set
o.Diagnostics.EvaluateWhileClosed = true: the rules then run as the app is used, not only while the
panel is open. In a test, BevSessionCheck.Check(json) and
BevProfileComparison.Compare(baseline, current) do the same without the tool.
A tool of your own
The page hub is the one way in for a frontend outside the panel, and it exists only while an enabled runtime is attached. A request goes to one runtime and comes back as JSON:
const hub = window.__BIT_BEVTOOLS__; for (const target of hub.targets()) { const hello = await hub.request(target.id, "hello"); // snapshot (the bit-bevtools/1 export, by section, or the timeline after an event id), // inspect, expand, command and export: documented on BevToolsProtocol const snapshot = await hub.request(target.id, "snapshot", { sections: ["diagnostics"] }); }