In Blazor, JavaScript Interop allows C# code to call JavaScript functions and vice versa. This is essential when interacting with browser APIs, accessing localStorage, manipulating the DOM, or working with third-party JS libraries. Blazor provides two main interfaces for this purpose: IJSRuntime and IJSInProcessRuntime.

IJSRuntime – Asynchronous Interop

This is the standard way to call JavaScript from C# in both Blazor Server and Blazor WebAssembly. It uses asynchronous calls to avoid blocking the UI thread.

When to Use:

  • The app runs on Blazor Server or needs cross-platform compatibility.
  • You are calling long-running or async JavaScript functions.

UI responsiveness is a priority.

@inject IJSRuntime JS
<button @onclick="SaveToLocalStorage">Save</button><button @onclick="ReadFromLocalStorage">Read</button>@code { async Task SaveToLocalStorage() { await JS.InvokeVoidAsync("localStorage.setItem", "title", "Blazor Blog"); } async Task ReadFromLocalStorage() { string value = await JS.InvokeAsync<string>("localStorage.getItem", "title"); Console.WriteLine($"Value from localStorage: {value}"); }
}

IJSInProcessRuntime – Synchronous Interop

This is a more specialized interface for Blazor WebAssembly only. It allows synchronous calls to JavaScript, which can reduce latency in performance-critical scenarios.

When to Use:

  • The app runs only on Blazor WebAssembly.
  • You need fast, synchronous access to JS (e.g., reading small values).
  • The JS function is quick and doesn’t block the UI thread.
@inject IJSRuntime JSRuntime
<button @onclick="ReadSync">Read Sync</button>@code { void ReadSync() { if (JSRuntime is IJSInProcessRuntime jsInProcess) { string title = jsInProcess.Invoke<string>("localStorage.getItem", "title"); Console.WriteLine($"(Sync) Value: {title}"); } }
}

What are the Key Differences IJSRuntime vs IJSInProcessRuntime?

FeatureIJSRuntime (Async)IJSInProcessRuntime (Sync)
Available InBlazor Server & WebAssemblyBlazor WebAssembly only
Call TypeAsynchronousSynchronous
Thread SafetyNon-blocking, UI-safeCan block UI if misused
Usage RecommendationPreferred for most scenariosUse only for small, fast calls

Conclusion

Use IJSRuntime for safe, asynchronous JS interop across both hosting models. Only use IJSInProcessRuntime in Blazor WebAssembly when you need fast synchronous access for lightweight operations. Avoid blocking the UI thread and always consider portability and performance when choosing between the two.