NE.Standard

Overview

NE.Standard is a server-driven UI framework for .NET. You write a view — a component tree, in C# fluent builders — and a controller — an observable object graph. The framework compiles that pair once into an immutable, indexed description, renders it to a platform, and then keeps the rendered surface in sync with the controller in both directions. The client never holds application state and never decides what to draw.

Web is the platform implemented today: ASP.NET Core for the shell and the transport, SignalR for the live channel, and a TypeScript client that ships embedded in the assembly — there is no separate front-end deploy step. The core is platform-neutral; a second platform renders the same views and controllers (platforms).

This is a pre-release. Every package goes out on one repository version, and the public surface is still expected to move between them.

Install

dotnet add package NE.Standard.UI.Web --prerelease
dotnet add package NE.Standard.UI.Web.Renderers --prerelease

Everything else in the framework arrives as a dependency of those two; the packages page lists what each one carries and how they layer.

A first look

A view declares the tree and what each part binds to:

internal sealed class CounterView : UIViewBase, IUIViewDefinition
{
    public static string ViewKey => "counter";

    protected override IVisualComponent CreateContent()
        => new ContainerComponent()
            .SetPadding(new UIThickness(16))
            .AddChild(new TextComponent()
                .BindTitle(nameof(CounterController.Count))
                .SetPlacement(1, 1, 24, 1)
            )
            .AddChild(new ButtonComponent()
                .OnClick(nameof(CounterController.Increment))
                .ConfigureDefaultContent(c => c.SetTitle("Add one"))
                .SetPlacement(1, 2, 24, 1)
            );
}

A controller holds the state, and changing it is what updates the screen — [RecursiveMember] generates the notifying setter and the path segment the binding resolves against:

internal sealed partial class CounterController : UIControllerBase
{
    [RecursiveMember]
    public partial int Count { get; set; }

    [UICommand]
    public void Increment() => Count++;
}

Hosting is an ASP.NET Core application:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

WebStartupBuilder.Configure<AppWebStartup, AppStartup>(builder.Services);

WebApplication app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
await app.MapStandardUIWebAsync();
await app.RunAsync();

Where to go next

License

The Prosperity Public License 3.0.0 — free for noncommercial use, with a thirty-day trial for commercial use. Personal projects, research, education, charities and public institutions are not commercial use. Read the licence; it is one page.