BlazorCodeFirst 0.1.0-preview.2

This is a prerelease version of BlazorCodeFirst.
dotnet add package BlazorCodeFirst --version 0.1.0-preview.2
                    
NuGet\Install-Package BlazorCodeFirst -Version 0.1.0-preview.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="BlazorCodeFirst" Version="0.1.0-preview.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlazorCodeFirst" Version="0.1.0-preview.2" />
                    
Directory.Packages.props
<PackageReference Include="BlazorCodeFirst" />
                    
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 BlazorCodeFirst --version 0.1.0-preview.2
                    
#r "nuget: BlazorCodeFirst, 0.1.0-preview.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 BlazorCodeFirst@0.1.0-preview.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=BlazorCodeFirst&version=0.1.0-preview.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=BlazorCodeFirst&version=0.1.0-preview.2&prerelease
                    
Install as a Cake Tool

BlazorCodeFirst

Write Blazor components as ordinary C# instead of .razor markup. A Roslyn source generator folds each Body into RenderTreeBuilder calls at build time. At run time there is no UI tree to interpret, no reflection, and no expression compilation.

You write this:

using BlazorCodeFirst;
using Microsoft.AspNetCore.Components;
using static BlazorCodeFirst.Html;

[Route("/notices")]
public partial class NoticePage : BodyComponentBase
{
    private int _seen;

    protected override View Body =>
        Div.Class("notice")[
            H2["Release notes"],
            P["Nothing new today."],
            Button.OnClick(() => _seen++)[$"Seen {_seen} times"]];
}

The generator emits this, and it is what ships:

partial class NoticePage
{
    protected override void RenderView(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
    {
        __builder.OpenElement(0, "div");
        __builder.AddAttribute(1, "class", "notice");
        __builder.AddMarkupContent(2, "<h2>Release notes</h2><p>Nothing new today.</p>");
        __builder.OpenElement(3, "button");
        __builder.AddAttribute(4, "onclick", global::Microsoft.AspNetCore.Components.EventCallback.Factory.Create(this, () => _seen++));
        __builder.AddContent(5, $"Seen {_seen} times");
        __builder.CloseElement();
        __builder.CloseElement();
    }
}

What the pair shows:

  • H2 and P are both static, so they collapsed into a single AddMarkupContent frame.
  • The sequence numbers are literals the generator assigned, not values counted while rendering.
  • NoticePage is an ordinary ComponentBase descendant, so Blazor diffs it exactly as it diffs a Razor component, and it stays trimming-safe and AOT-safe.

The vocabulary mirrors HTML

Elements are C# helpers named after their tags. Attributes and events sit next to the tag in a decoration chain, children follow in brackets, and layout is left entirely to CSS. That puts BlazorCodeFirst in the lineage of kotlinx.html, Scalatags, Feliz and hiccup rather than SwiftUI or Jetpack Compose. There are no VStack / HStack / Grid containers, and no typed .Padding() / .FontSize() decorations.

Body is a typed C# expression, so the compiler checks names and types, and refactorings propagate through it. What C# cannot check is the shape of a Body:

  • a component that forgets partial
  • state mutated inside Body
  • a decoration applied to something that is not a single element
  • a duplicate attribute
  • a non-constant tag name

The analyzers report those as BCF**** diagnostics during the build.

Requirements

.NET SDK 10.0.100 or later, and a net10.0 Blazor project. The generator ships as a Roslyn 5.0 analyzer, so an older compiler refuses to load it. In an IDE, that means Visual Studio 2026 version 18.0 or later.

Installation

dotnet add package BlazorCodeFirst --prerelease

This is a prerelease, which is what --prerelease is for: without it the command resolves the latest stable version instead, of which there is none. The surface is deliberately narrow and grows one issue at a time. The single package carries both halves: the runtime in lib/net10.0, and the generator and analyzers in analyzers/dotnet/cs.

Documentation

  • Documentation site: getting started, elements and decorations, control flow, layouts. The site is itself written in BlazorCodeFirst.
  • Repository: the design overview (DESIGN.md), the compilation algorithm and the diagnostic table (ARCHITECTURE.md), and the issue tracker.

License

MIT.

Product Compatible and additional computed target framework versions.
.NET 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
0.1.0-preview.2 72 8/21/2026