Blazor.Browser.DevTools 1.1.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Blazor.Browser.DevTools --version 1.1.2
                    
NuGet\Install-Package Blazor.Browser.DevTools -Version 1.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Blazor.Browser.DevTools" Version="1.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Blazor.Browser.DevTools" Version="1.1.2" />
                    
Directory.Packages.props
<PackageReference Include="Blazor.Browser.DevTools" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Blazor.Browser.DevTools --version 1.1.2
                    
#r "nuget: Blazor.Browser.DevTools, 1.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Blazor.Browser.DevTools@1.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Blazor.Browser.DevTools&version=1.1.2
                    
Install as a Cake Addin
#tool nuget:?package=Blazor.Browser.DevTools&version=1.1.2
                    
Install as a Cake Tool

Blazor Dev Tools

ko-fi NuGet License: LGPL v3

A React DevTools-like experience for Blazor applications (Server and WebAssembly). Inspect your component tree, view parameters and cascading values, and understand what the dependency injection container resolved, all from a dedicated Blazor panel inside Chrome DevTools.

Blazor Dev Tools has two cooperating parts:

Part Location Role
Blazor library (NuGet) Blazor.Browser.DevTools Hooks into the Blazor runtime, inspects components via reflection, and exposes inspection data over a JSON protocol
Chrome Extension src/Extension DevTools panel, background relay, and content-script bridge that renders the inspection data

Features

  • Cross-Platform Blazor Support: Works with Blazor Server and Blazor WebAssembly
  • Component Tree Inspection: Live, nested view of the rendered component hierarchy
  • Parameter & Cascading Value Viewing: See parameter names, declared types, and serialized values per component
  • Dependency Injection Introspection: Inspect injected services with their declared service type and resolved implementation type
  • Element Picker & Highlight Overlay: Pick an element on the page and highlight the matching component (and vice versa) using best-effort CSS locators
  • Development-Only by Default: A runtime gate keeps Dev Tools off outside Development, so nothing is exposed in production
  • Multi-Targeted: Ships for .NET 9 and .NET 10
  • Clean DI Registration: A single builder.Services.AddBlazorDevTools() call and one <DevToolsInitializer /> component

Installation

Install the NuGet package into your Blazor app:

dotnet add package Blazor.Browser.DevTools

Then install the Blazor Dev Tools Chrome extension (see Installing the Chrome extension).

Quick Start

1. Register Services

In your Program.cs:

using BlazorDevTools.Client.DependencyInjection;

builder.Services.AddBlazorDevTools();

Registration is safe in any environment. Dev Tools stays disabled at runtime unless the host environment is Development (see Security).

2. Add the Initializer Component

Render <DevToolsInitializer /> once, somewhere that runs after the app has rendered (for example, your root App.razor or MainLayout.razor). The initializer wires up the JS bridge, watches for navigation, and pushes component tree snapshots to the extension.

@* MainLayout.razor (or App.razor) *@
<DevToolsInitializer />

Make sure the namespace is available (via _Imports.razor or an inline @using):

@using BlazorDevTools.Client

3. Open the Panel

  1. Build and run your app.
  2. Install/load the Chrome extension (below).
  3. Open Chrome DevTools (F12) on your app and select the Blazor panel.

You should see the live component tree. Selecting a component shows its parameters, cascading values, and injected services.

Installing the Chrome extension

The extension is built from TypeScript sources under src/Extension.

cd src/Extension
npm install
npm run build

Then load it in Chrome:

  1. Open chrome://extensions
  2. Enable Developer mode
  3. Click Load unpacked
  4. Select the src/Extension folder

Re-run npm run build (or npm run watch) after changing extension TypeScript sources.

If the app loaded before the panel was open, hard-refresh the tab. The background worker buffers the last envelope per tab and flushes it when the panel connects.

Integration Scenarios

Scenario 1: New Blazor Server App

Step 1: Create New Project
dotnet new blazor -n MyBlazorApp
cd MyBlazorApp
Step 2: Install Package
dotnet add package Blazor.Browser.DevTools
Step 3: Configure Services

Update Program.cs:

using BlazorDevTools.Client.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

// Add Blazor Dev Tools (disabled at runtime outside Development)
builder.Services.AddBlazorDevTools();

var app = builder.Build();

// ... your usual pipeline ...

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.Run();
Step 4: Add the Initializer

In App.razor, render the initializer with an interactive render mode so it can use JS interop:

<body>
    <DevToolsInitializer @rendermode="@(new InteractiveServerRenderMode(prerender: false))" />
    <Routes @rendermode="InteractiveServer" />
    <script src="@Assets["_framework/blazor.web.js"]"></script>
</body>

On Blazor Server, static-SSR layout components are not part of the interactive renderer and will not appear in the tree. Components rendered interactively (and pages you navigate to) will.

Scenario 2: Existing Blazor Server App

Step 1: Install Package
dotnet add package Blazor.Browser.DevTools
Step 2: Add Service Registration

In your existing Program.cs, after your other registrations:

using BlazorDevTools.Client.DependencyInjection;

builder.Services.AddBlazorDevTools();
Step 3: Render the Initializer

Add <DevToolsInitializer /> once in your interactive root (for example App.razor with an interactive render mode, or an interactive MainLayout). No component changes are required; Dev Tools inspects the existing tree automatically.

Scenario 3: Blazor WebAssembly App

Step 1: Install Package
dotnet add package Blazor.Browser.DevTools
Step 2: Configure Services

Update Program.cs:

using BlazorDevTools.Client.DependencyInjection;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

// Add Blazor Dev Tools
builder.Services.AddBlazorDevTools();

await builder.Build().RunAsync();
Step 3: Add the Initializer

In MainLayout.razor:

@inherits LayoutComponentBase

<div class="page">
    <main>
        @Body
    </main>
</div>

<DevToolsInitializer />

And ensure _Imports.razor exposes the namespace:

@using BlazorDevTools.Client

Configuration

AddBlazorDevTools() accepts an optional configuration callback exposing BlazorDevToolsOptions:

builder.Services.AddBlazorDevTools(options =>
{
    // null  -> auto: enabled only when the host environment is Development (default)
    // true  -> force enabled (local debugging only, NEVER in production)
    // false -> force disabled
    options.Enabled = null;
});
Option Type Default Description
Enabled bool? null When null, enablement resolves from IHostEnvironment matching Development. When the host environment is unavailable, the default is false. Set explicitly only for local debugging.

Development Configuration

// Default behavior: enabled only in Development, no extra setup required.
builder.Services.AddBlazorDevTools();

Production Configuration

// Recommended: register unconditionally; the runtime gate disables Dev Tools in Production.
builder.Services.AddBlazorDevTools();

Force-Enabled (local debugging only)

// NEVER ship this to production.
builder.Services.AddBlazorDevTools(o => o.Enabled = true);

Security

Blazor Dev Tools exposes sensitive application internals to the browser when enabled. The in-page bridge dispatches protocol envelopes via same-origin window.postMessage. Any same-origin script, not just the Chrome extension, can observe component names, serialized parameter values, DI injection metadata, and DOM locators.

Default behavior

Dev Tools is disabled unless IHostEnvironment.IsDevelopment() is true. When the host environment is unavailable, Dev Tools stays off. This is enforced at runtime via IBlazorDevToolsService.IsEnabled; you do not need the Chrome extension installed for the gate to apply. The Blazor app simply does not dispatch envelopes when disabled.

Integration patterns

Pattern A (recommended): Register and render unconditionally; the runtime gate disables Dev Tools in Production.

builder.Services.AddBlazorDevTools();
<DevToolsInitializer />

Pattern B (optional optimization): Skip registration outside Development and conditionally render <DevToolsInitializer />. Both steps are required; registration alone without the component does nothing, and rendering alone without registration causes a DI failure.

if (builder.Environment.IsDevelopment())
{
    builder.Services.AddBlazorDevTools();
}

Explicit override

AddBlazorDevTools(o => o.Enabled = true) is available for local debugging scenarios. Never use this in production.

Edge environments

  • Staging is off by default (not Development).
  • Misconfigured production with ASPNETCORE_ENVIRONMENT=Development will enable Dev Tools; ensure production deployments use the Production environment.
  • Blazor WebAssembly: the client bundle ships whatever you register. The WASM host environment may differ from the server host environment; verify production-like behavior with dotnet publish -c Release and serve the publish output.

Verifying the production gate

When testing that Production suppresses Dev Tools, use a page-level listener in the inspected tab's DevTools Console; an empty Blazor panel alone is not sufficient proof (the extension may buffer stale envelopes):

window.addEventListener("message", (e) => {
  if (e.data?.protocol === "blazor-devtools") console.log("LEAK", e.data);
});

Expect zero LEAK logs after page load, navigation, and panel refresh. Use a fresh incognito window or clear extension session storage before negative tests.

Architecture Overview

The Chrome extension knows nothing about Blazor internals. It consumes a standardized JSON messaging protocol. The Blazor library handles reflection, runtime inspection, and dependency-injection introspection.

flowchart LR
  devtoolsPanel["DevTools Panel"]
  backgroundSw["Background Service Worker"]
  contentScript["Content Script"]
  jsonProtocol["JSON Messaging Protocol"]
  blazorLib["Blazor.Browser.DevTools (library)"]

  devtoolsPanel --> backgroundSw
  backgroundSw --> contentScript
  contentScript --> jsonProtocol
  jsonProtocol --> blazorLib

Message flow:

  1. DevTools panel (panel.html / panel.js) renders the component tree and property inspector.
  2. Background service worker (background.js) relays messages between the panel and the inspected tab.
  3. Content script (content.js) is injected into the page and bridges to the in-page Blazor runtime via same-origin window.postMessage.
  4. Blazor library (Blazor.Browser.DevTools) inspects components and serializes state into the JSON protocol.

Wasm vs. Server hosting is abstracted inside the library so both hosting models are exercised with the same extension.

Common Issues & Solutions

Issue 1: Service Not Registered

Error: InvalidOperationException: Unable to resolve service for type 'IBlazorDevToolsService'

Solution: Add the registration to Program.cs:

builder.Services.AddBlazorDevTools();

If you render <DevToolsInitializer /> without registering services, you will get this DI failure. Register and render together (Pattern A).

Issue 2: Empty Blazor Panel

Problem: The Blazor panel shows no component tree.

Solutions:

  1. Confirm you are running in Development (or have explicitly enabled Dev Tools for local debugging).
  2. Ensure <DevToolsInitializer /> is rendered with an interactive render mode (Server) so JS interop is available.
  3. Hard-refresh the inspected tab if it loaded before the panel was opened.
  4. Open the Blazor panel before navigating, or navigate to force a fresh snapshot.

Issue 3: Components Missing on Blazor Server

Problem: Layout or page components do not appear.

Solution: Static-SSR components are not part of the interactive renderer and are not inspected. Render the relevant components interactively to see them in the tree.

Issue 4: Locator/Highlight Not Working

Problem: Element highlight does not line up with a component.

Solution: Locators are best-effort CSS selectors for a component's first rendered element and may be unavailable for components without a stable root element. This is expected for some components.

License

This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0). See the LICENSE, COPYING, and COPYING.LESSER files for details.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for build steps, conventions, and PR guidelines.

Changelog

See CHANGELOG.md for a list of changes and version history.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.3 101 6/20/2026
1.1.2 89 6/20/2026
1.1.1 94 6/20/2026
1.1.0 92 6/20/2026
1.0.1 103 6/17/2026

See CHANGELOG.md for details.