November 2023, Revisited: .NET 8 and the Blazor Unification

Eric Greene June 11, 2026

Our Three-Year Retrospective reaches November 2023 and the release of .NET 8 on November 14, during that year's .NET Conf. It was an LTS release, which in the .NET world means it was the version enterprises would actually standardize on, and it carried one change that reshaped how teams built web UI on the platform: Blazor stopped being two products pretending to be one, and became a single full-stack model.

The question Blazor finally stopped asking

From its beginning, Blazor forced an awkward up-front decision. Blazor Server ran your components on the server and shipped UI diffs over a SignalR connection — fast first load, but every interaction cost a network round trip and every user held a persistent connection. Blazor WebAssembly ran .NET in the browser — full client-side interactivity, but a heavy initial download and a cold start users could feel. You picked one per application, at file-new-project time, before you knew which trade-off your app actually needed.

.NET 8 dissolved the dichotomy. Blazor gained static server-side rendering as its default mode: components render to plain HTML on the server, no SignalR, no WASM payload, just fast pages — finally making Blazor sensible for the content-heavy pages that had always been its weakest case. On top of that sat streaming rendering, which flushed the page shell immediately and streamed in content as async data arrived, killing the blank-page-while-awaiting-the-database problem.

And then the headline: per-component interactive render modes. A page could be static, with one island marked @rendermode InteractiveServer or InteractiveWebAssembly. The InteractiveAuto mode went further — render via the server connection first for instant interactivity, download the WASM runtime in the background, and switch to client-side execution on subsequent visits. The architecture decision moved from "per application, forever" to "per component, changeable."

@page "/counter"
@rendermode InteractiveServer

<button @onclick="Increment">Clicked @count times</button>

@code {
    private int count;
    private void Increment() => count++;
}

We remember teaching this in late 2023 to teams who had previously rejected Blazor, and watching the objection list shrink in real time. It was the same conceptual move React was making with server components in the same era — the industry converging, from different directions, on "render on the server by default, hydrate islands where needed."

Native AOT and the runtime's steady gains

The other durable .NET 8 story was Native AOT maturing. Ahead-of-time compilation to a self-contained native binary — no JIT, no runtime to install, dramatically smaller memory footprint and millisecond startup — moved from intriguing to practical, with ASP.NET Core minimal APIs gaining real (if constrained) support. The constraints were honest: no runtime code generation meant trouble for reflection-heavy libraries, and the ecosystem began the long work of becoming trim- and AOT-friendly, source generators replacing reflection one library at a time. For containerized microservices and serverless functions, where cold start and memory were billable, the payoff was immediate.

Around all this, the runtime team delivered its annual ritual humiliation of last year's benchmarks — dynamic PGO on by default was the big one — and C# 12 added primary constructors and collection expressions. Solid, compounding, unglamorous.

Why the LTS label mattered

.NET 8's three-year support window made it the consolidation point for the platform's whole post-Framework era. Organizations still straggling on .NET 6 — or on Framework 4.8 with a migration plan gathering dust — now had a destination with modern performance, a complete web story, and support through 2026. November 2023 kicked off a wave of upgrade projects that ran well into the following year.

Looking back from June 2026

The unified Blazor model won. The render-mode architecture introduced here carried forward through .NET 9 and 10 essentially intact — refined, but not rethought — which tells you the design was right. Native AOT's library-compatibility story improved release over release, and the "static first, interactive islands" pattern stopped being novel and became simply how .NET web applications are built. Teams adopting Blazor today never face the Server-versus-WASM question that defined its first four years; most do not know it existed.

That post-unification world is exactly what we teach. Build .NET 10 Web Apps with Blazor works through render modes, streaming, and component architecture on the current LTS, and TDD with .NET 10, Blazor, and Web API layers test-driven practice over the same stack — including how to test components whose render mode is a design decision, a question that only exists because of what shipped this month in 2023.