Fact-checked by Grok 2 weeks ago

Blazor

Blazor is a free and open-source developed by as part of , enabling developers to build interactive web user interfaces (UIs) using C# and .NET instead of , with support for reusable components, data binding, and integration with and CSS. It originated as an experimental project in 2018, achieved official preview status in April 2019, and saw its server-side hosting model (Blazor Server) released with .NET Core 3.0 on September 23, 2019, while the client-side model (Blazor WebAssembly) became generally available in May 2020. Blazor supports multiple hosting models to suit different application needs: Blazor Server uses for real-time UI updates from the server, providing low latency for apps but requiring a persistent connection; Blazor WebAssembly runs .NET code directly in the browser via , allowing offline capabilities and reduced server load; and Blazor Hybrid integrates web technologies into native desktop or mobile apps using frameworks like MAUI or WPF. With the release of 8 in , Blazor evolved into a unified full-stack framework called Blazor Web Apps, combining server-side rendering for initial loads with optional client-side interactivity, enhancing performance and . Key features include component-based architecture for modular UI development, built-in support for forms, validation, and state management, as well as seamless interop for leveraging existing libraries. The framework runs on supported platforms including Windows, Linux, and macOS, and extends to web, mobile, and desktop via integrations like .NET MAUI, making it versatile for full-stack .NET development. Blazor's ecosystem includes official project templates in and VS Code, along with third-party components from vendors like and DevExpress, and open-source libraries for . As of .NET 10 in 2025, ongoing enhancements focus on improved reconnection handling, JavaScript interoperability, and state persistence, positioning Blazor as Microsoft's preferred UI framework for applications.

History

Origins and Development

Blazor originated as a personal project by Steve Sanderson, a engineer, who first demonstrated a at the NDC Oslo conference in June 2017. The project aimed to enable developers to build interactive web user interfaces using C# and the .NET ecosystem directly in the browser, bypassing the need for for client-side logic. Sanderson's initial vision was to leverage , an emerging web standard, to run .NET code client-side, allowing full-stack development with a single language while reusing existing .NET libraries and tools. In February 2018, the team at formally adopted Blazor as an experimental open-source project under their organization, marking its transition from a solo effort to a team-backed initiative. Key contributors included Sanderson, along with team members such as Daniel Roth and David Fowler, who expanded the framework's scope to include both and server-side rendering models. The primary goal was to empower .NET developers to create single-page applications (SPAs) without plugins or dependencies, integrating seamlessly with the broader .NET ecosystem for shared code across client and server. At Connect(); 2018 in December, Blazor was highlighted as a core component of the .NET Core 3 Preview 1 announcement, signaling 's commitment to its maturation. Blazor's early development faced significant hurdles due to the nascent state of WebAssembly, which was still maturing in 2018 with limited browser support initially confined to and , requiring polyfills or fallbacks for broader compatibility. Bundle size was another concern, as the initial .NET runtime for WebAssembly resulted in larger downloads compared to traditional frameworks, impacting initial load times on slower connections. Despite these challenges, the project progressed rapidly, culminating in its elevation from experimental status to an official .NET component in 2019 with the release of .NET Core 3.0 previews, introducing Blazor Server for real-time server-side rendering and early WebAssembly support for client-side execution.

Key Releases and Milestones

Blazor's development has progressed through annual .NET releases, each introducing significant enhancements to its hosting models, performance, and developer experience. The framework achieved a major milestone with the release of .NET 5 in November 2020, which delivered stable support for Blazor , allowing production deployment of client-side applications running .NET code in the browser via . This version also introduced preview support for ahead-of-time (AOT) compilation in experimental builds, alongside improved hosting capabilities such as enhanced trimming for smaller app sizes and better integration with hosted scenarios. In November 2021, .NET 6 solidified Blazor WebAssembly as fully production-ready with substantial performance optimizations, including up to 2-3x faster startup times compared to prior previews, and introduced .NET Hot Reload for Blazor projects. Hot Reload enabled developers to modify C# code, markup, and CSS in running applications without restarting the server or browser, streamlining iteration in both Blazor and WebAssembly modes. These updates were complemented by AOT compilation previews now more accessible for testing, further reducing runtime overhead. .NET 7, released in November 2022, focused on refining Blazor's rendering capabilities with enhanced streaming rendering support in Blazor Server, enabling partial UI updates over connections for more responsive applications, and introduced global interactivity options to simplify component event handling across scopes. Additional improvements included better Hot Reload support for adding new types and methods in Blazor , along with new data binding modifiers like @bind:after for post-binding logic. These changes prioritized smoother development workflows and reduced latency in interactive scenarios. The .NET 8 release in November 2023 marked a unification effort with the new Blazor Web App template, supporting multiple render modes—static server-side rendering (SSR), interactive server-side rendering, and interactive WebAssembly—within a single project for flexible full-stack development. Streaming rendering saw major advancements, allowing components to render progressively as data loads, improving perceived performance for data-heavy UIs. This version also enhanced form handling with built-in model binding and validation directly in components, reducing reliance on custom JavaScript. With .NET 9 in November 2024, Blazor received refinements to the QuickGrid component, including new parameters like OverscanCount for optimized virtualized rendering of large datasets, and improved form handling with support for range inputs in InputNumber<TValue>, enabling native slider controls with full validation integration. These updates emphasized efficiency in data display and user input scenarios without external libraries. The most recent .NET 10, released in November 2025, introduced inline boot configuration by embedding blazor.boot.[json](/page/JSON) directly into dotnet.[js](/page/JS++) for simpler deployment, and state persistence via the [PersistentState] attribute in PersistentComponentState for declarative handling of user data across sessions. Enhanced interop added methods like InvokeConstructorAsync for dynamic object creation from .NET, while circuit persistence maintained Blazor Server sessions during temporary disconnects, such as network issues. Integration of passkey support via /FIDO2 was added to templates, bolstering . A milestone was the Blazor United initiative, emphasizing unified full-stack .NET development across all render modes to streamline hybrid server-client architectures.

Fundamentals

Components and Razor Syntax

Blazor components serve as the fundamental building blocks of Blazor applications, encapsulating reusable portions of the along with their associated processing logic. These components are defined using syntax, which seamlessly integrates markup, C# code, and CSS styles within a single file, enabling developers to create self-contained, nestable UI elements that can be composed to form complex applications. The structure of a Blazor component is typically housed in a .razor file, where it inherits from the ComponentBase class to gain access to core functionality such as rendering and lifecycle . Key elements include the @page directive, which defines for the component by associating it with a path, such as @page "/counter" to make it accessible via navigation. The component's is primarily composed of markup, which can include expressions like @ to embed dynamic C# values or logic directly into the markup. C# code is placed within an @code block (or multi-line @{ ... } for more complex logic), housing fields, properties, methods, and event handlers that manage the component's state and behavior. Component parameters facilitate data passing from to components, declared as public properties annotated with the [Parameter] attribute, allowing customization without tight . For two-way data binding, the @bind directive attribute synchronizes values between the component's properties and UI elements, such as form inputs, ensuring updates propagate bidirectionally. Blazor components follow a defined lifecycle to handle initialization, updates, and rendering. The OnInitializedAsync method executes once after the initial parameters are set, ideal for setup tasks like loading data that do not depend on parameter changes. OnParametersSetAsync runs after parameters are updated, including on the first render and subsequent parent rerenders, making it suitable for reacting to input changes. OnAfterRenderAsync invokes after the component renders to the , providing a firstRender to distinguish initial renders, and is commonly used for post-render operations like focusing elements. These asynchronous methods allow for non-blocking operations, with synchronous counterparts available for simpler scenarios. A representative example is the component, which demonstrates basic structure, , and event handling:
razor
@page "/counter"

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}
This component uses the @page directive for , for display, an @onclick event bound to a method in the @code block, and syntax to interpolate the currentCount value. During rendering, Blazor compiles the component into an in-memory representation known as a render tree, which combines the DOM structure and CSS information; the then efficiently updates the actual DOM by diffing the new render tree against the previous one, minimizing unnecessary manipulations. Various hosting models execute these components to produce the final output in the browser. To manage dependencies and , Blazor provides directives such as @using to import namespaces (often globally in _Imports.razor), @inject for of services into fields or constructor parameters, and @inherits to specify a custom base class beyond ComponentBase. These directives enhance modularity and reusability without cluttering the component file.

Data Binding and Event Handling

Blazor supports one-way data binding to display data from component properties or fields directly in the rendered markup using expressions prefixed with @. For instance, in a component, <p>Current count: @currentCount</p> renders the of the currentCount property and updates automatically when the property changes during a component re-render. Two-way data binding enables synchronization between elements and component , allowing user input to update properties and vice versa. This is achieved with the @bind directive on supported elements like inputs, where <input @bind="name" /> binds the input's value attribute to the name property and the onchange to update it. Developers can customize the binding by specifying the value attribute with @bind:get and the with @bind:event, such as @bind-value="name" @bind:event="oninput" for immediate updates on keystrokes, or use @bind:set to control the setter invocation. Event handling in Blazor uses Razor directives like @onclick to attach C# s to DOM s, triggering component re-renders upon completion. For example, <button @onclick="Increment">Click me</button> calls the Increment , defined as private void Increment() => currentCount++;, which can pass arguments like MouseEventArgs for details such as coordinates: @onclick:preventDefault="true" @onclick="HandleClick". s support asynchronous operations via s returning Task, ensuring responsiveness during delays, as in private async Task IncrementAsync() { await Task.Delay(500); currentCount++; }. The EventCallback<T> type facilitates async invocation and parameter passing, preventing unnecessary re-renders if the parent component does not update. Custom events allow child components to notify parents of actions, promoting reusable parent-child communication without direct references. A child component exposes an EventCallback<T> property, such as [Parameter] public EventCallback<int> OnIncrement { get; set; }, and invokes it with await OnIncrement.InvokeAsync(currentCount); in response to internal events. The parent then binds to this callback, e.g., <ChildComponent OnIncrement="ParentIncrement" />, where ParentIncrement handles the passed value. This pattern supports generic types for flexible data passing, like EventCallback<MouseEventArgs>. Form handling in Blazor leverages the EditForm component for structured and validation, binding to a model object via the Model parameter: <EditForm Model="@starship">. It integrates with EditContext for custom validation logic and supports input components like InputText that inherit from InputBase<TValue> for type-safe , e.g., <InputText @bind-Value="starship.Identifier" />. Validation uses DataAnnotations attributes on the model, such as [Required] or [StringLength(3)], automatically checked on form submission or field changes; custom validators can extend ValidationMessage or implement IValidator. Errors are displayed with <ValidationSummary /> or <ValidationMessage For="@(() => starship.Identifier)" />, providing user feedback without manual state management. In .NET 10, Blazor's form validation was enhanced to support nested validation for complex objects and collections using source generators for efficiency and AOT compatibility. Developers apply the [ValidatableType] attribute to the root model class, e.g., [ValidatableType] public class Order { public Customer Customer { get; set; } public List<OrderItem> Items { get; set; } }, enabling recursive validation of nested properties like Customer.FullName with DataAnnotations. This requires calling builder.Services.AddValidation(); in Program.cs and defining models in separate C# files to support source generation, improving performance over reflection-based approaches in prior versions.

Hosting Models

Blazor Web App with Render Modes

The Blazor Web App template, introduced in .NET 8, provides a unified project structure that supports multiple render modes within a single application, enabling developers to mix static server-side rendering (SSR) with interactive components rendered on the server or client side. This model allows for flexible hosting, where components can be prerendered on the server for fast initial loads and SEO benefits, then transition to interactive modes as needed, without requiring separate projects for different hosting scenarios. Static server-side rendering (SSR) in Blazor Web Apps pre-renders on the server without any interactivity, producing lightweight, non-interactive pages that load quickly and are crawlable by search engines. Components or pages using this mode do not require the @rendermode directive or explicitly set it to @rendermode:Static, resulting in pure output served directly to the . This approach is ideal for content-heavy pages where user interaction is minimal or handled via traditional forms. Interactive Server rendering enables real-time UI updates by executing components on the server and streaming changes to the client via a connection, supporting full interactivity with low initial payload. Developers specify this mode using @rendermode InteractiveServer on components or pages, which establishes a persistent circuit for event handling and . Prerendering is enabled by default to show initial content while the connection initializes, and enhanced navigation preserves state during client-side routing. Interactive rendering shifts execution to the client-side .NET in the , downloading the necessary assemblies for independent operation after an optional prerender. This mode is set with @rendermode InteractiveWebAssembly and benefits from ahead-of-time (AOT) compilation in .NET 8 and later, which improves startup time and performance by compiling C# to ahead of deployment. It suits applications requiring offline capabilities or reduced load. Interactive Auto mode combines server and rendering by starting with Interactive Server for immediate interactivity, then seamlessly switching to once the client loads, optimizing for both fast startup and long-term . Configured via @rendermode InteractiveAuto, it can be applied globally in the application's Program.cs or per-component, with the transition handled automatically to maintain . Location-based variants allow specifying render modes for specific routes. Prerendering serves as an optional initial server-side render for interactive modes like and , generating static that hydrates into an interactive component on the client, thereby enhancing perceived load times and . Developers can disable it for specific components using custom render mode instances, such as new InteractiveWebAssemblyRenderMode(prerender: false). In .NET 10, Blazor Web Apps gain the ReconnectModal component in the default project template, which provides a customizable for handling disconnects in Interactive Server mode, including states like "retrying" and events for tracking reconnection progress. Additionally, enhanced prerendered state persistence uses the [PersistentState] attribute to declaratively retain component and service state across mode transitions and navigations, preventing UI flicker and without manual intervention.

Blazor WebAssembly Standalone

Blazor WebAssembly Standalone is a hosting model that enables the execution of .NET applications entirely within the browser, leveraging WebAssembly to run C# code without any server-side processing after the initial download. In this model, the .NET runtime is downloaded to the client browser, where it interprets and executes the application's assemblies, allowing for full client-side interactivity similar to traditional single-page applications (SPAs) built with JavaScript frameworks. This approach differs from server-involved models by eliminating ongoing server communication for UI updates, focusing instead on static asset delivery and local computation. The execution process begins with the browser downloading the .NET and the application's assemblies via , typically resulting in a bundle size of approximately 2-5 MB depending on optimizations like the IL Trimmer, which removes unused code. Once loaded, the handles component rendering, event processing, and directly in the 's JavaScript , using interop to manipulate the DOM and access features. App bundles include the , framework assemblies, and custom code, all compressed for efficient transfer and cached by the to support subsequent visits. Deployment for Blazor WebAssembly Standalone involves publishing the application as static files, which can be hosted on any web server, (CDN), or static hosting service like Static Web Apps, without requiring a dedicated for runtime execution post-download. After the initial asset download, the application operates independently, making it suitable for scenarios where low server overhead is prioritized. Key features include support for offline functionality through service workers, which cache essential assets like the runtime and assemblies, enabling the app to load and function without an connection after the first visit. Additionally, Blazor WebAssembly Standalone apps can be configured as Progressive Web Apps (PWAs) by adding a web app manifest, allowing installation on devices and providing app-like experiences with offline capabilities. In .NET 10, several enhancements improve the standalone model's efficiency, including client-side fingerprinting for JavaScript modules enables better caching and faster reloads by generating unique hashes for assets, while the new ResourcePreloader component facilitates proactive loading of critical resources to minimize perceived load times. Hot Reload is now enabled by default in Debug mode, allowing developers to iterate quickly without full recompilation. Despite these advancements, limitations persist, such as the initial load time required to download and initialize the , which can impact on slower networks or devices. Direct access to certain browser APIs is restricted, necessitating JavaScript interop for operations like file handling or geolocation, which introduces minor costs compared to native access. The boot process is initiated by the dotnet.js script, which loads the runtime and configures the application environment before executing the . In .NET 10, boot configuration via boot.json is inlined directly into the for streamlined startup, reducing the need for separate file fetches.

Blazor Hybrid

Blazor Hybrid enables the development of interactive web user interfaces using .NET and components within native client applications, leveraging an embedded Web View for rendering without relying on . This approach combines web technologies with native frameworks, allowing developers to build cross-platform applications that run directly on devices. Supported platforms include desktop environments such as Windows via WPF and , as well as cross-platform desktop and mobile through .NET MAUI, which targets Windows, macOS, , and . These applications gain full access to native device APIs, such as sensors, file systems, and hardware features, through standard .NET interfaces. Setup involves integrating the BlazorWebView or MauiBlazorWebView control into the native app's , which hosts the embedded browser and loads components from an or local files. Developers configure the Web View using like BlazorWebViewInitializing for setup and BlazorWebViewInitialized for post-initialization tasks, enabling seamless rendering of components within the native shell. Key advantages include significant code sharing between web and native projects, as components and .NET libraries can be reused across platforms without platform-specific code. This reduces development effort while maintaining high performance through native execution and direct integration. In .NET 10, Blazor Hybrid benefits from improved state persistence across the application lifecycle using the declarative [PersistentState] attribute, which simplifies managing component and service state during scenarios like or app suspension. Additionally, OwningComponentBase now implements IAsyncDisposable, providing DisposeAsync and DisposeAsyncCore methods for asynchronous resource cleanup, enhancing reliability in long-running native apps. Common use cases encompass extending Progressive Web Apps (PWAs) into native distributions for better device integration or constructing full native applications where C# handles UI logic alongside native features, such as in enterprise mobile tools or desktop productivity software.

Advanced Features

JavaScript Interoperability

Blazor provides JavaScript interoperability (JS interop) to enable seamless integration between C# code and , allowing applications to leverage browser APIs and existing JavaScript libraries while maintaining a primarily .NET-based model. This bidirectional communication is essential for tasks such as DOM manipulation, accessing device features, or incorporating third-party scripts that are not yet natively supported in Blazor. The interop mechanism relies on the Microsoft.JSInterop namespace and is available in both Blazor WebAssembly and Blazor Server hosting models, though with differences in latency and threading considerations. To invoke JavaScript functions from .NET code, developers inject the IJSRuntime interface, which provides asynchronous methods for calling . The primary method is InvokeAsync<T>, where T specifies the expected return type, enabling the execution of global or scoped JS functions with JSON-serializable arguments. For instance, to display a alert, code might use await JSRuntime.InvokeAsync<string>("alert", "Hello from Blazor!");, which passes the string argument to the native alert function and awaits its completion without a return value. A void-returning variant, InvokeVoidAsync, is used when no result is needed, such as triggering a non-returning JS operation. These calls are asynchronous to accommodate the non-blocking nature of applications and must reference JS functions relative to the global scope or via imported modules. Conversely, can invoke .NET methods marked with the [JSInvokable] attribute, facilitating callbacks from browser events or scripts to Blazor components. These methods must be public and can be static or instance-based; static methods are called directly via DotNet.invokeMethodAsync('AssemblyName', 'MethodName'), while instance methods require creating a DotNetObjectReference to maintain a strong reference and prevent garbage collection. For example, a C# method [JSInvokable] public static async Task<string> GetDataAsync(string input) could be invoked from JS as DotNet.invokeMethodAsync('MyApp', 'GetDataAsync', 'inputValue').then(result => console.log(result));, returning the processed string asynchronously. Proper disposal of DotNetObjectReference instances is crucial to avoid memory leaks in long-running applications. In .NET 10, Blazor's JS interop was enhanced with new methods on IJSRuntime to simplify object manipulation without repeated function invocations. InvokeConstructorAsync allows creating instances of JS objects by calling their constructors, returning an IJSObjectReference for further interaction, such as await JSRuntime.InvokeConstructorAsync("[Date](/page/Date)", DateTime.UtcNow);. Property access is streamlined via GetValueAsync<T> to retrieve values, e.g., await JSRuntime.GetValueAsync<string>("someObject.[property](/page/Property)");, and SetValueAsync to update them, like await JSRuntime.SetValueAsync("someObject.[property](/page/Property)", "newValue");. Synchronous variants are available through IJSInProcessRuntime for in-process scenarios, and improved handling of byte arrays reduces overhead by avoiding unnecessary encoding in high-performance transfers. These additions promote more efficient, object-oriented interop patterns. Data marshaling between .NET and JavaScript relies on automatic JSON serialization using System.Text.Json, which handles primitives, arrays, and objects with public properties and default constructors. Complex types are serialized to JSON strings for transmission, with member names camel-cased by default; deserialization supports flexible casing via JsonElement. For custom types or performance-critical scenarios, developers can implement JsonConverter classes with the [JsonConverter] attribute to override serialization logic, such as for non-standard formats or to optimize large payloads. Byte arrays benefit from direct interop to bypass JSON overhead, enhancing efficiency for binary data. Best practices emphasize minimizing interop calls to optimize , as each invocation incurs and context-switching overhead. Developers should batch operations where possible, use C# wrappers around common like localStorage to abstract repetitive calls, and prefer JS modules for isolated, reusable scripts. For example, a wrapper might encapsulate storage operations: public async Task SetLocalStorage(string key, string value) => await JSRuntime.InvokeVoidAsync("localStorage.setItem", key, value);. Avoiding synchronous interop in contexts prevents UI blocking, and profiling tools should be used to identify high-frequency calls for refactoring. Limitations include the single-threaded execution model in Blazor WebAssembly, where JS interop must be asynchronous to avoid halting the UI thread during browser API access. In server-side Blazor, interop calls traverse the connection, introducing network latency and size limits on payloads (typically 4 KB for reliable transmission). All interop requires proper error handling for JS exceptions via JSException, and scenarios restrict calls until the interactive is established. These constraints necessitate careful design to balance .NET purity with necessary JS integration.

State Management and Persistence

Blazor provides several built-in mechanisms for managing application state across its hosting models, enabling developers to share data between components and services while handling lifecycle events such as rendering and reconnection. These techniques ensure that user interactions remain consistent without relying on external frameworks for basic scenarios. One fundamental approach is the use of the CascadingValue component, which allows data to flow down the component hierarchy from an ancestor to multiple descendant components without explicit parameter passing. This is particularly useful for providing shared context, such as theme settings or state, to deeply nested UI elements. For instance, a root-level CascadingValue can supply a service instance or value that child components access via the [CascadingParameter] attribute. Dependency injection (DI) complements this by facilitating state management through services with defined lifetimes: Scoped services maintain state for the duration of a user session or circuit in Blazor Server, while Singleton services preserve state across the application's lifetime, suitable for global caches or configurations. Services are registered in the DI container during app startup, and components inject them to access or mutate shared state, promoting loose coupling and testability. For persistence, Blazor offers the IPersistentComponentState service, which enables of component state after , preventing when transitioning from static server-rendered to interactive execution. Developers inject this service into components and use methods like PersistAsJson to store serializable state, which is then restored on the client via a hidden form field or similar mechanism during the initial render. Browser-based storage, such as localStorage or sessionStorage, can be accessed via JavaScript interop for longer-term persistence in apps, where state would otherwise reside solely in memory and be lost on page refresh. Introduced in .NET 10, the [PersistentState] attribute provides a declarative way to mark fields or properties in components and services for automatic persistence using the PersistentComponentState service, simplifying without manual calls. This attribute supports options like AllowUpdates for controlling restoration behavior during and RestoreBehavior for customizing logic. Developers can extend through custom implementations of IPersistentComponentStateSerializer, allowing support for complex types beyond . Additionally, .NET 10 enhances circuit state persistence in Blazor Server by retaining user session data during SignalR disconnects, browser tab throttling, app pauses, or network interruptions, using in-memory caching (default retention: 2 hours for up to 1,000 circuits) or distributed options like HybridCache (default: 8 hours). This ensures seamless reconnection without full state recreation, improving resilience in interactive server scenarios. For more complex applications, patterns inspired by or Redux can be implemented using libraries like Fluxor, a zero-boilerplate solution that enforces unidirectional data flow through actions, reducers, and a centralized store. Fluxor integrates seamlessly with Blazor's component model, dispatching actions to update immutable state and notifying subscribers for re-renders, which is ideal for handling asynchronous operations and large-scale apps. In Blazor Server specifically, server-side state is inherently managed within the circuit, where component instances and scoped services hold the hierarchy and render output until disconnection, at which point .NET 10's persistence features mitigate loss. In prerendering scenarios for Blazor WebAssembly, state computed on the server during initial render is transferred to the client to avoid redundant API calls or computations upon hydration. The IPersistentComponentState service facilitates this by serializing state on the server and deserializing it on the client, ensuring continuity in hybrid hosting models where static and interactive renders coexist.

Performance and Security

Optimization Techniques

Blazor applications can be optimized across hosting models to reduce load times and enhance runtime efficiency, particularly in scenarios where initial download size and compilation impact . Key techniques focus on minimizing bundle sizes, improving rendering efficiency, and leveraging caching and compression. These strategies are applicable to Blazor WebAssembly standalone apps and models, while server-side optimizations emphasize management. Bundle trimming, also known as IL trimming, removes unused code from assemblies during publishing, significantly reducing the download size of Blazor apps. To enable it, set <PublishTrimmed>true</PublishTrimmed> in the project's .csproj file and publish with dotnet publish -c Release. This process analyzes code usage to eliminate unnecessary IL, though it requires careful testing to avoid trimming essential reflection-dependent code. Ahead-of-time (AOT) compilation transforms .NET code into native binaries before runtime, eliminating overhead and improving execution speed for compute-intensive operations in Blazor WebAssembly apps. Enable AOT by adding <RunAOTCompilation>true</RunAOTCompilation> to the .csproj file, available since .NET 7, and publish in Release mode. While it boosts runtime performance, it doubles the initial app size due to native , making it suitable for apps where startup time is less critical than ongoing . In .NET 10, new diagnostic counters provide detailed into Blazor app performance, tracking metrics for component lifecycle events (such as rendering and disposal), flows, and event handling. These counters integrate with OpenTelemetry for exporting traces and metrics to tools like Application Insights, enabling proactive identification of bottlenecks in and server-side circuits. Developers can collect data using dotnet-counters or browser dev tools, with examples showing reduced latency through targeted optimizations. Caching mechanisms in Blazor optimize static asset delivery by fingerprinting files with SHA-256 hashes in blazor.boot.json, allowing browsers to cache .NET , assemblies, and app bundles while validating integrity on load. Preloading is facilitated via HTTP Link headers for critical resources like and data, reducing subsequent fetches. The BlazorCacheBootResources property, which previously controlled boot resource caching, is removed in .NET 10 in favor of standard browser caching behaviors. Rendering optimizations prevent unnecessary UI updates, preserving efficiency in interactive apps. Overriding the ShouldRender method in ComponentBase allows components to skip re-rendering if state changes are irrelevant, such as ignoring parameter updates that don't affect output. For data-heavy tables, the QuickGrid component employs to render only visible rows, supporting large datasets (e.g., thousands of items) with scrolling, which can significantly improve performance compared to full rendering. WebAssembly-specific techniques further enhance Blazor's client-side performance. compression, applied statically during publish at the highest level, reduces file sizes more effectively than for .NET —while servers automatically serve compressed variants based on client headers. of assemblies defers downloading non-essential modules until route activation, cutting initial payload by loading only core runtime and resources first, configurable via assembly mapping in blazor.boot.json.

Security Considerations

Blazor applications leverage 's authentication mechanisms, primarily integrating with ASP.NET Core Identity to manage user accounts, including registration, login, and profile management. This integration is particularly seamless in Blazor Web Apps, where scaffolding provides UI components for identity operations, and authentication state is propagated via the AuthenticationStateProvider. For external providers, Blazor supports OpenID Connect (OIDC) and , with sample implementations demonstrating secure token handling and user consent flows in the Blazor Web App template. Authorization in Blazor relies on components like CascadingAuthenticationState, which cascades the current authentication state to child components, and the AuthorizeView component, which conditionally renders content based on user roles or policies. The [Authorize] attribute can be applied to components or pages to enforce , ensuring that sensitive operations are restricted server-side where possible, as client-side checks in are considered untrusted. In .NET 10, these features are enhanced with updated security samples in Blazor Web Apps, including role-based access examples. Recent updates in .NET 10 introduce support for in Blazor Web Apps, utilizing the Web Authentication API (WebAuthn) integrated with . Developers configure this by updating the Identity schema to 3 and adding endpoints for passkey creation and assertion, with UI components like PasskeySubmit handling prompts for registration and sign-in. Additionally, .NET 10 improves form validation through unified APIs in the Microsoft.Extensions.Validation package, enabling stronger prevention of injection attacks via attributes like [Required] and custom validators on Blazor forms. Security samples now include JWT handling in minimal APIs, demonstrating token validation and issuance for API endpoints consumed by Blazor components. Common threats in Blazor include connection hijacking in interactive server-side rendering modes, where unauthorized access to circuits could lead to data leakage or manipulation. Mitigation involves enforcing handshakes during connection establishment and avoiding the reflection of user-controlled content in compressed responses to prevent side-channel attacks like or . (XSS) risks arise from JavaScript interop, where unsanitized inputs could execute malicious code; developers should validate all interop parameters, prefer AddContent over AddMarkupContent for rendering, and implement Content Security Policies (CSP) to restrict script sources. In static server-side rendering, prerendered may expose sensitive data or app structure, necessitating careful authorization checks and avoidance of embedding confidential information. For Blazor Hybrid apps, threats from untrusted Web View content require sandboxing iframes and prohibiting unsafe JavaScript practices like eval. Best practices for Blazor security emphasize validating all using DataAnnotations attributes in models to guard against injection and other exploits. Applications must enforce to protect data in transit, and developers should avoid storing or exposing sensitive data—such as credentials or —in client-accessible locations like prerendered or local storage. (CSRF) is addressed through built-in antiforgery , automatically included in EditForm components via the AntiforgeryToken element, which generates hidden fields validated on submission. For state persistence across sessions, secure storage mechanisms should be used to prevent unauthorized access to cached data.

Ecosystem and Tools

Development Tools

Blazor development relies on a suite of official tools integrated into the .NET ecosystem to streamline the creation, debugging, and testing of applications. serves as the primary (), offering comprehensive support through Blazor-specific project templates that scaffold complete applications, including components, routing, and layout structures. It provides full IntelliSense functionality for syntax, enabling autocompletion, error highlighting, and navigation within .razor files that blend , CSS, and C# code. For developers preferring a lightweight editor, (VS Code) supports Blazor via the official C# extension, which delivers similar IntelliSense, , and task running capabilities, though with less integrated than . Command-line interface (CLI) tools from the .NET SDK further enhance workflow efficiency by automating project setup and iterative development. The dotnet new blazor command generates a new Blazor Web App project, configurable for interactive render modes, including options for WebAssembly or server-side hosting. For rapid iteration, dotnet watch enables hot reload, automatically rebuilding and refreshing the application upon file changes without losing state, supporting modifications to C#, Razor, CSS, and HTML. In .NET 9 and later, WebAssembly-specific hot reload is enabled by default in Debug configuration via the WasmEnableHotReload MSBuild property set to true, allowing seamless updates during browser-based development. Additionally, .NET 10 introduces WasmBundlerFriendlyBootConfig, an MSBuild property that, when set to true during publish, produces JavaScript bundler-compatible output for Blazor WebAssembly apps, facilitating integration with modern build pipelines like Webpack or Vite. Debugging tools are tightly integrated to support both client-side and server-side Blazor models. For Blazor WebAssembly, browser developer tools—such as those in DevTools or Edge Inspector—allow inspection of .NET code, setting breakpoints, and stepping through execution directly in the browser console after enabling source maps. extends this with full debugger attachment for Blazor Server apps, enabling server-side breakpoints, variable inspection, and analysis within the IDE, akin to traditional debugging. Testing frameworks recommended by focus on component isolation and end-to-end validation. The bUnit library, a community-driven but officially endorsed tool, facilitates unit and of components by rendering them in a host, mocking dependencies, and asserting rendered output or invoked services. For end-to-end (E2E) testing, for .NET provides cross-browser automation, simulating user interactions across Blazor apps hosted in various environments while verifying full application behavior.

Community and Extensions

The Blazor community is vibrant and largely open-source, centered around contributions to the official repository maintained by , where developers can submit issues, pull requests, and enhancements to the framework's core components. Active participation includes improving WebAssembly runtime integration, component rendering, and JavaScript interop features, with guidelines for contributions outlined in the project's documentation. The community also engages through official channels like the ASP.NET Community Standups, live streams hosted by engineers that discuss roadmap planning, performance optimizations, and user feedback for Blazor in .NET releases. Developers connect via established platforms such as , where the [blazor] tag has facilitated thousands of discussions on implementation challenges and best practices since the framework's inception. Community-driven events further foster collaboration, including annual conferences like Blazor Day, a gathering organized by MVPs focusing on advanced topics, tooling, and real-world applications. Other notable events include TrailBlazor, a free conference dedicated to Blazor, .NET , and related ecosystems, and sessions at .NET Conf, where present updates on Blazor's evolution. Blazor's ecosystem thrives on extensions and third-party libraries that enhance its capabilities, with many available via and . Popular open-source component libraries include MudBlazor, a Material Design-based UI kit offering over 60 responsive components like data grids, charts, and dialogs, widely adopted for its customization and performance. Radzen Blazor provides a free suite of 100+ native components, including schedulers, charts, and data editors, emphasizing enterprise-grade features without licensing costs. Other prominent options are Blazorise, a flexible supporting multiple CSS themes (Bootstrap, , AntDesign) for rapid UI development, and Fluent UI Blazor, Microsoft's official components aligned with Windows design principles. Utility extensions expand Blazor's functionality beyond UI, such as Blazor.Extensions for browser APIs like , handling, and capture, enabling features directly in C#. For development tools, Visual Studio extensions like the official Blazor project templates streamline scaffolding, while vendor-specific ones from Syncfusion and integrate pre-built components into IDE workflows for faster prototyping. Curated resources like the Awesome Blazor catalog hundreds of such extensions, helping developers discover integrations for , , and testing.

References

  1. [1]
    Blazor | Build client web apps with C# | .NET
    Blazor is a feature of ASP.NET for building interactive web UIs using C# instead of JavaScript. It's real .NET running in the browser on WebAssembly.Enhance Your Blazor... · Blazor Success Stories · Explore The Blazor Ecosystem
  2. [2]
    Blazor now in official preview! - .NET Blog
    Apr 18, 2019 · With this newest Blazor release we're pleased to announce that Blazor is now in official preview! Blazor is no longer experimental and we are ...
  3. [3]
    Blazor WebAssembly 3.2.0 now available - .NET Blog
    May 19, 2020 · I'm thrilled to announce that Blazor WebAssembly is now officially released. This is a fully-featured and supported release of Blazor ...
  4. [4]
    ASP.NET Core Blazor hosting models - Microsoft Learn
    Nov 12, 2024 · This article explains Blazor hosting models, primarily focused on Blazor Server and Blazor WebAssembly apps in versions of .NET earlier than .NET 8.
  5. [5]
    What's new in ASP.NET Core in .NET 8 | Microsoft Learn
    This article highlights the most significant changes in ASP.NET Core in .NET 8 with links to relevant documentation.Blazor · SignalR
  6. [6]
    ASP.NET Core Blazor - Microsoft Learn
    Nov 12, 2024 · Blazor is a .NET frontend web framework that supports both server-side rendering and client interactivity in a single programming model.Blazor supported platforms · Blazor hosting models · Blazor project template
  7. [7]
    A new experiment: Browser-based web apps with .NET and Blazor
    Feb 6, 2018 · Today I'm excited to announce a new experimental project from the ASP.NET team called Blazor. Blazor is an experimental web UI framework ...
  8. [8]
    Announcing .NET Core 3 Preview 1 and Open Sourcing Windows ...
    Dec 4, 2018 · Today, we are announcing .NET Core 3 Preview 1. It is the first public release of .NET Core 3. We have some exciting new features to share ...
  9. [9]
    Web Development - C# in the Browser with Blazor | Microsoft Learn
    Blazor is the new Microsoft experimental framework that brings C# into any browser without a plug-in. It holds the promise of modern single-page applications.C# In The Browser With... · Adding The Zip Code Web... · Adding The Weather...Missing: origins history Connect
  10. [10]
    Announcing .NET 5.0 - Microsoft Developer Blogs
    Nov 10, 2020 · The runtime and libraries for Blazor WebAssembly are now built from the consolidated dotnet/runtime repo. That means Blazor WebAssembly and ...
  11. [11]
    ASP.NET Core updates in .NET 6 Preview 3
    Apr 8, 2021 · Early support for .NET Hot Reload is now available for ASP.NET Core & Blazor projects using dotnet watch . .NET Hot Reload applies code changes ...Smaller Signalr, Blazor... · Http/3 Endpoint Tls... · Vcpkg Port For Signalr C++...<|control11|><|separator|>
  12. [12]
    What's new in ASP.NET Core in .NET 6 - Microsoft Learn
    Oct 18, 2024 · This change improves build performance, enables single file deployment, and enables these types to participate in Hot Reload. For more ...
  13. [13]
    What's new in ASP.NET Core in .NET 7 - Microsoft Learn
    Sep 27, 2024 · In .NET 7, the HTML markup has been recombined with the _Host page in project templates. Several additional changes were made to the Blazor ...Rate limiting middleware in... · Authentication uses single...
  14. [14]
    What's new in ASP.NET Core in .NET 9 | Microsoft Learn
    Nov 19, 2024 · Interactive WebAssembly rendering in Blazor now supports client-side request streaming using the request.SetBrowserRequestStreamingEnabled ...Missing: 5 | Show results with:5
  15. [15]
    What's new in ASP.NET Core in .NET 10 | Microsoft Learn
    Sep 15, 2025 · In standalone Blazor WebAssembly apps during build/publish, the framework overrides placeholders in index.html with values computed during build ...
  16. [16]
    ASP.NET Core Razor components - Microsoft Learn
    Nov 12, 2024 · This article explains how to create and use Razor components in Blazor apps, including guidance on Razor syntax, component naming, namespaces, and component ...Built-in Razor components · Blazor layouts · Templated components · Data Binding
  17. [17]
    ASP.NET Core Razor component lifecycle - Microsoft Learn
    Mar 18, 2025 · Use streaming rendering with static server-side rendering (static SSR) or prerendering to improve the user experience for components that ...Missing: 7 | Show results with:7
  18. [18]
    ASP.NET Core Blazor data binding - Microsoft Learn
    This article explains data binding features for Razor components and DOM elements in Blazor apps. Binding features. Razor components provide data binding ...
  19. [19]
    ASP.NET Core Blazor event handling - Microsoft Learn
    Nov 12, 2024 · This article explains Blazor's event handling features, including event argument types, event callbacks, and managing default browser events.Delegate event handlers · Built-in event arguments
  20. [20]
    ASP.NET Core Blazor forms binding - Microsoft Learn
    Nov 12, 2024 · This article explains how to use binding in Blazor forms. EditForm / EditContext model An EditForm creates an EditContext based on the assigned object as a ...
  21. [21]
    ASP.NET Core Blazor forms validation
    ### Summary of Nested Validation, `[ValidatableType]`, and Source Generators in Blazor Forms Validation for .NET 10
  22. [22]
    ASP.NET Core Blazor render modes - Microsoft Learn
    Aug 8, 2025 · To enable global interactivity when creating a Blazor Web App: Visual Studio: Set the Interactivity location dropdown list to Global. .NET ...
  23. [23]
  24. [24]
    ASP.NET Core Blazor prerendered state persistence - Microsoft Learn
    Sep 9, 2025 · Alternatively, update the app to .NET 10 or later, where Blazor supports handling persistent component state when during enhanced navigation.
  25. [25]
    ASP.NET Core Blazor app download size performance best practices
    May 6, 2025 · Trimming unused assemblies from a Blazor WebAssembly app reduces the app's size by removing unused code in the app's binaries.Missing: early maturity
  26. [26]
    Host and deploy ASP.NET Core Blazor WebAssembly
    Apr 11, 2025 · This article explains how to host and deploy Blazor WebAssembly apps. With the Blazor WebAssembly hosting model:.
  27. [27]
    ASP.NET Core Blazor Progressive Web Application (PWA)
    Jul 7, 2025 · A Blazor Progressive Web Application (PWA) is a single-page application (SPA) that uses modern browser APIs and capabilities to behave like a desktop app.
  28. [28]
    What's new in .NET 10 - Microsoft Learn
    The ASP.NET Core 10.0 release introduces several new features and enhancements, including Blazor improvements, OpenAPI enhancements, and minimal API updates.Microsoft Ignite · EF Core 10 · Cryptography · What's new in the SDK and...
  29. [29]
    ASP.NET Core Blazor performance best practices - Microsoft Learn
    Aug 12, 2025 · Guidance on ASP.NET Core Blazor metrics and tracing, improving app performance, and avoiding common performance problems.Missing: stable 5<|control11|><|separator|>
  30. [30]
    ASP.NET Core Blazor JavaScript interoperability (JS interop)
    Nov 19, 2024 · A Blazor app can invoke JavaScript (JS) functions from .NET methods and .NET methods from JS functions. These scenarios are called JavaScript interoperability ...Call JavaScript functions from... · JavaScript location in ASP...Missing: history | Show results with:history
  31. [31]
    ASP.NET Core Blazor startup - Microsoft Learn
    Apr 4, 2025 · This article explains Blazor app startup configuration. For general guidance on ASP.NET Core app configuration for server-side development, see Configuration ...Startup process and... · JavaScript initializers
  32. [32]
    ASP.NET Core Blazor Hybrid - Microsoft Learn
    Dec 10, 2024 · This article explains ASP.NET Core Blazor Hybrid, a way to build interactive client-side web UI with .NET in an ASP.NET Core app.Blazor Hybrid apps with .NET... · Blazor Hybrid apps with WPF...
  33. [33]
    Host a Blazor web app in a .NET MAUI app using BlazorWebView
    The .NET MAUI BlazorWebView control enables you to host a Blazor web app in your .NET MAUI app, and integrate the app with device features.
  34. [34]
  35. [35]
    Reuse Razor components in ASP.NET Core Blazor Hybrid apps
    Dec 5, 2024 · This article explains how to author and organize Razor components for the web and Web Views in Blazor Hybrid apps.
  36. [36]
  37. [37]
    Call JavaScript functions from .NET methods in ASP.NET Core Blazor
    Apr 15, 2025 · This article explains how to invoke JavaScript (JS) functions from .NET. For information on how to call .NET methods from JS, see Call .NET methods from ...
  38. [38]
  39. [39]
    Call .NET methods from JavaScript functions in ASP.NET Core Blazor
    Dec 17, 2024 · This article explains how to invoke .NET methods from JavaScript (JS). For information on how to call JS functions from .NET, see Call JavaScript functions ...
  40. [40]
  41. [41]
  42. [42]
  43. [43]
    ASP.NET Core Blazor JavaScript interoperability (JS interop ...
    May 6, 2025 · JavaScript [JSImport] / [JSExport] interop for Blazor WebAssembly apps offers improved performance and stability over the JS interop API in framework releases ...
  44. [44]
    ASP.NET Core Blazor state management overview - Microsoft Learn
    Aug 8, 2025 · This article and the other articles in this node describe common approaches for maintaining a user's data (state) while they use an app and ...State management using the... · In-memory state container...
  45. [45]
    ASP.NET Core Blazor cascading values and parameters
    Feb 25, 2025 · Cascading values and parameters provide a convenient way to flow data down a component hierarchy from an ancestor component to any number of descendent ...Root-level cascading values · Root-level cascading values...
  46. [46]
    ASP.NET Core Blazor dependency injection - Microsoft Learn
    Oct 27, 2025 · This article explains how Blazor apps can inject services into components. Dependency injection (DI) is a technique for accessing services configured in a ...Missing: syntax | Show results with:syntax
  47. [47]
    ASP.NET Core Blazor server-side state management - Microsoft Learn
    Aug 8, 2025 · During server-side rendering, Blazor Web Apps can persist a user's session (circuit) state when the connection to the server is lost for an ...<|control11|><|separator|>
  48. [48]
    Fluxor is a zero boilerplate Flux/Redux library for Microsoft ... - GitHub
    The aim of Fluxor is to create a multi-UI, single-state store approach to front-end development without the headaches typically associated with other ...
  49. [49]
    Trim self-contained applications - .NET - Microsoft Learn
    The trim-self-contained deployment model is a specialized version of the self-contained deployment model that is optimized to reduce deployment size.
  50. [50]
    ASP.NET Core Blazor WebAssembly build tools and ahead-of-time ...
    Blazor WebAssembly supports ahead-of-time (AOT) compilation, where you can compile your .NET code directly into WebAssembly. AOT compilation results in runtime ...
  51. [51]
    ASP.NET Core Blazor WebAssembly caching and integrity check ...
    Jul 15, 2025 · This article explains asset caching for Blazor WebAssembly and how to diagnose and resolve integrity failures.
  52. [52]
    ASP.NET Core Blazor rendering performance best practices
    May 6, 2025 · Optimize rendering speed to minimize rendering workload and improve UI responsiveness, which can yield a ten-fold or higher improvement in UI rendering speed.
  53. [53]
    ASP.NET Core Blazor `QuickGrid` component - Microsoft Learn
    Mar 17, 2025 · The QuickGrid component is a Razor component for quickly and efficiently displaying data in tabular form, providing a simple data grid ...
  54. [54]
    Lazy load assemblies in ASP.NET Core Blazor WebAssembly
    Dec 2, 2024 · Blazor WebAssembly app startup performance can be improved by waiting to load developer-created app assemblies until the assemblies are required, which is ...
  55. [55]
    ASP.NET Core Blazor authentication and authorization
    Oct 30, 2025 · This article describes ASP.NET Core's support for the configuration and management of security in Blazor apps. Blazor uses the existing ASP.
  56. [56]
    Secure an ASP.NET Core Blazor Web App with OpenID Connect ...
    Jul 29, 2025 · This article describes how to secure a Blazor Web App with OpenID Connect (OIDC) using a sample app in the dotnet/blazor-samples GitHub repository.Missing: considerations | Show results with:considerations<|control11|><|separator|>
  57. [57]
    Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID
    Jul 30, 2025 · This article describes how to secure a Blazor Web App with Microsoft identity platform with Microsoft Identity Web packages for Microsoft Entra ID using a ...Missing: considerations | Show results with:considerations
  58. [58]
    Implement passkeys in ASP.NET Core Blazor Web Apps
    Oct 30, 2025 · Currently, only the Blazor Web App project template includes built-in passkey support. ... An existing Blazor Web App (.NET 10 or later) with ASP.
  59. [59]
  60. [60]
    Threat mitigation guidance for ASP.NET Core Blazor interactive ...
    Nov 19, 2024 · This topic describes common threats to server-side Blazor apps and provides threat mitigation guidance focused on Internet-facing apps.Missing: 10 | Show results with:10
  61. [61]
    Threat mitigation guidance for ASP.NET Core Blazor static server ...
    Nov 19, 2024 · This article explains the security considerations that developers should take into account when developing Blazor Web Apps with static server-side rendering.
  62. [62]
    ASP.NET Core Blazor Hybrid security considerations - Microsoft Learn
    Nov 12, 2024 · This article describes security considerations for Blazor Hybrid apps. Blazor Hybrid apps that render web content execute .NET code inside a platform Web View.
  63. [63]
    Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP ...
    Oct 10, 2025 · Using local storage to store the antiforgery token on the client and sending the token as a request header is a recommended approach. Blazor.Authentication fundamentals · Antiforgery in ASP.NET Core
  64. [64]
    Tooling for ASP.NET Core Blazor - Microsoft Learn
    Nov 12, 2024 · For a standalone Blazor WebAssembly experience, choose the Blazor WebAssembly App template, which includes demonstration code and Bootstrap ...
  65. [65]
    Debug ASP.NET Core Blazor apps - Microsoft Learn
    Feb 3, 2025 · This article describes how to debug Blazor apps, including debugging Blazor WebAssembly apps with browser developer tools or an integrated development ...<|separator|>
  66. [66]
    Test Razor components in ASP.NET Core Blazor - Microsoft Learn
    Nov 12, 2024 · bUnit is an example of a library that enables Razor component unit testing. ... Counter component in an app based on a Blazor project template.<|control11|><|separator|>
  67. [67]
    Blazor Day 2025 | Microsoft Reactor
    Learn new skills, meet new peers, and find career mentorship. Virtual events are running around the clock so join us anytime, anywhere!Missing: forums contributions
  68. [68]
    2025 TrailBlazor Conference – For Blazor, .NET MAUI & Oqtane ...
    The 2025 TrailBlazor Conference is a virtual .NET community event for Blazor, .NET MAUI, and Oqtane developers, on June 26, 2025.
  69. [69]
    .NET Conf 2025
    Join the .NET Conf 2025 free virtual event November 11-13 to learn about the newest developments across the .NET platform, open source, and dev tools.Agenda · Local events · This year's speakers · Secret Decoder ChallengeMissing: Blazor | Show results with:Blazor
  70. [70]
    Blazor Extensions - GitHub
    Curated extensions for Microsoft ASP.Net Core Blazor. Popular repositories Loading Canvas Canvas Public HTML5 Canvas API implementation for Microsoft Blazor.
  71. [71]
    Progress Telerik UI for Blazor Extension - Visual Studio Marketplace
    Oct 2, 2025 · The package includes ready-to-use Blazor WebAssembly and Server Project Templates with Telerik Grid, Chart, Form Inputs and Dashboard layout.
  72. [72]
    AdrienTorris/awesome-blazor - GitHub
    A collection of awesome Blazor resources. Blazor is a .NET web framework using C#/Razor and HTML that runs in the browser with WebAssembly.AdrienTorris/awesome-blazorActions