Heimdall Docs
HTML-first ASP.NET Core UI

Server-rendered interfaces that still feel alive.

Heimdall lets ASP.NET Core return HTML for pages, interactions, out-of-band updates, and live streams without turning every workflow into a client-side app.

HTML over the wire
No JSON view model ceremony
Server-owned state
Less client synchronization
Razor friendly
Reuse MVC partials

A smaller loop for serious web apps.

Keep rendering close to the business logic, return the markup the browser needs, and let small attributes describe how the DOM should change.

Pages are HTML

Map routes to server-rendered HTML without forcing Razor, JSON APIs, or a JavaScript application shell.

Actions return fragments

Handle clicks, forms, filters, validation, and list updates by returning the exact HTML to swap.

Live updates stay native

Use Bifrost SSE when the server needs to push fresh HTML after the original request is gone.

One mental model, many surfaces.

Heimdall does not care whether the HTML came from fluent rendering, MVC partials, Bootstrap helpers, static generation, or your own template layer.

01

Render

Return a page, partial, row, panel, toast, or modal from ASP.NET Core.

02

Invoke

Use attributes or fluent helpers to call content actions with payloads.

03

Swap

Replace, append, prepend, or skip the target while out-of-band updates run.

04

Stream

Subscribe to scoped SSE topics when the server needs to speak first.

Bring the stack you already trust.

Use Heimdall in a purpose-built HTML-first app, inside MVC, or beside conventional controller routes. Start with one interaction and expand only where the server should own the workflow.

  • MVC and Razor partial rendering through the real view engine
  • Strongly typed Bootstrap helpers when you want server-side composition
  • CSRF, authorization metadata, request timeouts, and dependency injection
[ContentInvocationPrefix("orders")]
public sealed class Orders(
    IOrderRepository orders)
{
    [ContentInvocation("filter")]
    public IHtmlContent Filter(OrderFilter filter)
    {
        var rows = orders.Search(filter);
        return OrderTable.Render(rows);
    }
}

Keep the browser light. Let the server speak HTML.

Build the first route, wire one action, and feel how much client code you did not have to invent.

Open the getting started guide