Enter Blazor, a framework which lets you create a web application in C# and run it entirely in a browser. Blazor is a bleeding edge solution (it’s currently in preview) but it can already do the job of React and more. As a developer who knows React well, here are the things I did and didn’t enjoy while working on my first Blazor project during our Dev Camp this year. Familiarity with React is helpful but is not necessary, and please note that this article is about Blazor client-side not its server-side relative.
Blazor’s approach to UI is exactly the same as React’s, asking you build your UI up by nesting components and markup. Like a React component, a Blazor component can be passed parameters from its parent component and have internal state.
Blazor components are written as classes, and they have lifecycle methods reminiscent of React component classes. As React transitions to hooks this feels slightly outdated, and I found myself missing hook features like property-wise binding and memoisation.
Blazor borrows Razor syntax from ASP.NET to combine C# and markup. React has the upper hand here with JSX: in Razor, C# is a “guest” inside the markup, and in practice this is less powerful than having the markup as a guest inside the code. Visual Studio also currently has a frustrating amount of trouble formatting Razor files in a consistent way.
React focuses on drawing to the DOM, and as such if you want routing within your application you must implement it yourself or use a third-party library like react-router.
In Blazor, routing is feature of the framework. It’s driven by a simple, declarative directive in your component and it supports dynamic paths. I appreciated the simple design of this feature and prefer it to having to pick a third-party library in React.
Blazor provides a declarative syntax for data binding. I hit issues when trying to “chain” bindings (binding to a parameter which is already bound inside a parent) and find explicitly passing React-style “setter” function parameters more powerful and easier to debug than a special syntax.
As Blazor uses the .NET runtime it shouldn’t be surprising that you can import and run almost any C# code (almost since you can only use things that can live inside a browser, so no .NET HttpClient for example). This is extremely useful when you have code which needs to run both client and server-side. It’s something you can do with a React too, but only as long as your back end is Node.
async C# counterparts. The API is still brittle and disjointed, but could be greatly improved in the future with automatic type inference for code with Typescript declarations.
Prerendering happens when the server executes a client side application, takes a snapshot of the DOM and uses this for the markup it sends to the client. This makes the application appear to load faster in the browser and allows search engines to scrape your landing page more easily. Both Blazor and React support prerendering, but you will want to use a matching server stack (React with Node and Blazor with ASP.NET).
Blazor is definitely less polished in this regard. At the moment debugging is limited and troublesome or impossible to set up. It’s should be improved as the framework matures, but for my project I was forced to use to print debugging.
If you would like to explore Blazor further then we recommend the Awesome Blazor repo for examples of it in action.