Open source · MIT · .NET 9 & 10
Reactive web UIs, written in C#.
Natrix runs your C# in the browser on WebAssembly. Pages render on the server first, then fine-grained signals update exactly the DOM nodes that changed. No virtual DOM, no Razor, no JavaScript to write.
dotnet new install Natrix.Templatespublic class Counter : BaseComponent<NoProps, NoEvents, NoSlots, NoExpose>
{
protected override IComponent[] Setup(out NoExpose exposed)
{
exposed = default;
// Runs once. From here on, only what reads a signal updates.
var count = new Signal<int>(0);
var doubled = new Computed<int>(() => count.Value * 2);
return
[
new Button
{
Props = new ButtonProps(),
Events = new ButtonEvents { OnClick = _ => count.Value++ },
Children = [new DomText { Text = "Click me".ToConstSignal() }],
},
new P
{
Props = new PProps(),
Children = [new DomText { Text = new Computed<string>(
() => $"{count.Value} × 2 = {doubled.Value}") }],
},
];
}
}0 × 2 = 0
Counter.cs is the whole component, minus the styling. Its first render came from the server; each click now updates two text nodes and nothing else.
Why Natrix
Everything a modern UI framework gives you, in the language you already ship.
One language from the database to the DOM, with the type checker watching all of it. Natrix brings fine-grained reactivity in the spirit of SolidJS and Vue, and SWR-style data fetching, to .NET.
Fine-grained signals
Signal, Computed and Effect track their own dependencies. A change updates the one text node or attribute that reads it. Components never re-render, and there is no virtual DOM to diff.
Server-rendered, then hydrated
Every page arrives as complete HTML, so it paints fast and search engines can read it. The WebAssembly client then adopts the existing DOM instead of rebuilding it.
The whole Web platform, typed
C# bindings generated from the WebIDL specs: DOM, Fetch, Canvas, WebGL and more. IntelliSense for the browser, with no hand-written interop.
Tailwind, inside the compiler
The real Tailwind compiler runs during your build and emits only the classes your C# uses. No Node, no CLI and no watcher in your app.
Data fetching that feels instant
Stale-while-revalidate, ported from React SWR. Prefetch on the server, ship the cache inside the page, and revalidate in the background.
Ready for AOT, built for iteration
Trim- and AOT-safe throughout, down to source-generated JSON. Hot reload covers both your components and your styles while you work.
How it works
Fast on the first paint. Alive on the first click.
One component tree, rendered twice: once on the server for the HTML, once in the browser to make it interactive.
- 01
The server renders
ASP.NET Core runs your components and sends real HTML, with the data they need already fetched.
- 02
The browser paints
Content is visible, and indexable, before a single byte of .NET has been downloaded.
- 03
WebAssembly hydrates
The same components attach to the DOM that is already there. Signals take over, and nothing re-renders.
Examples
Don't take our word for it. Click around.
Every example runs live on this site, next to a link to its source.
Todo List
State, keyed list rendering, conditional rendering and child components reporting back through generated events.
Try it →Refs · Canvas API · LifecycleCanvas
Bouncing balls on the raw Canvas API, driven by requestAnimationFrame and cleaned up when the component unmounts.
Try it →SWR · Server prefetchData Fetching
Stale-while-revalidate over a real endpoint: prefetched on the server, with loading, retry and error states.
Try it →Your first Natrix app is three commands away.
The template gives you a server-rendered host, a WebAssembly client, routing and Tailwind, wired up and ready to change. Natrix is young and moving fast, so expect APIs to evolve, and tell us what you build.
# once$ dotnet new install Natrix.Templates# then, for every app$ dotnet new natrix -o MyApp$ dotnet watch --project MyApp/MyApp