DevTools & Diagnostics

Debug and monitor your Blazor state with powerful developer tools including Redux DevTools integration and built-in diagnostics.

Redux DevTools Integration

EasyAppDev.Blazor.Store seamlessly integrates with the Redux DevTools browser extension, bringing powerful time-travel debugging and state inspection to your Blazor applications.

Features

🕐 Time-travel debugging

Navigate through your application's state history, jump to any point in time, and replay actions.

📊 State diffs and inspection

View detailed state changes, compare before/after states, and inspect the current state tree.

🎬 Action replay

Replay specific actions to reproduce bugs and understand state transformations.

📸 Import/export snapshots

Save and share state snapshots for debugging, testing, or collaboration.

Installation

First, install the Redux DevTools browser extension:

More information: Redux DevTools GitHub

Render Mode Compatibility

Redux DevTools works in:

  • ✅ Blazor WebAssembly (full support)
  • ✅ Blazor Auto mode (activates automatically after WASM transition)
  • ⚠️ Blazor Server (gracefully skips - use logging middleware instead)

The library automatically detects the render mode and adapts accordingly. DevTools integration will silently skip initialization in Blazor Server mode without causing errors. See the Render Modes guide for detailed information.

Usage

Enable DevTools by using WithDefaults() when registering your store:

Program.cs
builder.Services.AddStoreWithUtilities(
    new AppState(),
    (store, sp) => store.WithDefaults(sp, "MyApp"));  // DevTools included!
What is WithDefaults()?

WithDefaults() is a convenience method that automatically configures:

  • Redux DevTools integration
  • Logging middleware
  • JSRuntime integration for browser APIs

Once enabled, open the Redux DevTools in your browser to:

  • View all state changes in real-time
  • Inspect the current state tree
  • Jump to any previous state (time-travel)
  • Export/import state snapshots

Diagnostics (DEBUG builds only)

For deeper insights during development, use the built-in diagnostics panel. This feature is only available in DEBUG builds and has zero overhead in production releases.

DEBUG Only

The diagnostics system is compiled out in RELEASE builds, ensuring zero performance impact in production. Use conditional compilation to include the diagnostic panel only in debug mode.

Setup

Register diagnostics services and configure your store to use them:

Program.cs
// Register diagnostics service
builder.Services.AddStoreDiagnostics();

// Configure store with diagnostics
builder.Services.AddStore(
    new CounterState(0),
    (store, sp) => store
        .WithDefaults(sp, "Counter")
        .WithDiagnosticsIfAvailable(sp));

Usage

Add the diagnostic panel to your component or page:

DiagnosticsPage.razor
#if DEBUG
<DiagnosticPanel DisplayMode="DiagnosticDisplayMode.Inline" />
#endif

What Does It Track?

📜 Action History

Complete log of all state updates with action names and timestamps.

📊 Performance Metrics

Track update times, identify slow operations, and monitor P95/P99 percentiles.

🎨 Render Tracking

See which components re-render on state changes and identify unnecessary updates.

🔗 Subscription Monitoring

View active subscriptions and detect potential memory leaks from undisposed subscribers.

Zero Production Overhead

Thanks to conditional compilation, all diagnostic code is completely removed from RELEASE builds. You get powerful debugging tools during development without any performance cost in production.

Best Practices

Naming Your Stores

Give your stores descriptive names to make debugging easier:

// Good: Descriptive names
store.WithDefaults(sp, "UserAuthentication")
store.WithDefaults(sp, "ShoppingCart")
store.WithDefaults(sp, "TodoList")

// Avoid: Generic names
store.WithDefaults(sp, "Store")
store.WithDefaults(sp, "State")

Action Names

Provide meaningful action names for better debugging:

// Explicit action names
await Update(s => s.Increment(), "INCREMENT_COUNTER");
await Update(s => s.AddTodo(text), "ADD_TODO");

// Or let the method name serve as the action
await Update(s => s.Increment());  // Auto-tracked as state change

Using Both Tools Together

Combine Redux DevTools and Diagnostics for maximum insight:

  • Redux DevTools: Track state changes and time-travel through history
  • Diagnostics: Monitor performance, renders, and subscriptions

Related Topics