Stonehenge 4
Open source · MIT licence · .NET 8 and .NET 10
Web user interfaces for .NET applications – with just C# and HTML
Stonehenge is an open-source framework for .NET based on the MVVM pattern. You write view models in C# and views in HTML; Stonehenge takes care of data binding, actions and live updates. The same application runs as a desktop window or as a web app in the browser.
app/start.html
<!--ViewModel:StartVm-->
<div>
<p>Hello from {{ComputerName}}!</p>
<p>Clicked: {{CountPressed}}</p>
<button class="btn btn-primary"
@click="ButtonPressed()">
Click me
</button>
</div> ViewModels/StartVm.cs
public class StartVm : ActiveViewModel
{
public string ComputerName => Environment.MachineName;
public int CountPressed { get; private set; }
[ActionMethod]
public void ButtonPressed()
{
CountPressed++;
}
} Hello Stonehenge Start
Hello from WORKSHOP-PC!
Clicked: 3
- in development since
- 2013
- licence, free for commercial use
- MIT
- supported .NET versions
- .NET 10 · 8
- operating systems: Windows, Linux, macOS
- 3
Why Stonehenge
The user interface in the browser, the logic in C#
Stonehenge combines proven web technology with the MVVM pattern .NET developers know. No client code of your own, no hand-written API.
-
One code base for desktop and web
The application opens in its own window of an installed browser – Chrome, Edge, Brave, Firefox or Safari – or runs as a web server for many users.
-
No hand-written API
Public properties and methods marked with [ActionMethod] are bound to the view automatically. No REST controller, no client proxy, no JSON mapping.
-
Live updates from the server
Server-sent events or polling: when a value in the view model changes, the browser shows it at once. An update timer delivers readings and status at a steady pace.
-
Authentication built in
Basic auth with an .htpasswd file (bcrypt, Apache MD5, SHA), NTLM on Windows and Keycloak – each with a single host option.
-
Multilingual, with themes
Texts from .resx resources, the language taken from the browser if you like. Themes as CSS files, selectable via the subdomain as well.
-
Kestrel, IIS or reverse proxy
Self-hosted with Kestrel or behind IIS; the base path and X-Forwarded headers are respected. Sessions without any cookies.
How it works
MVVM across the wire
Every page consists of an HTML view and a C# view model with a matching name. Stonehenge serves the view, keeps the view model on the server per session and keeps both in sync automatically.
View
HTML with Vue.js 2 templates and Bootstrap 5: {{binding}}, @click, v-for
actions and input
changed values
Stonehenge
Session, data binding, actions, server push via SSE or polling
actions and input
changed values
View model
C# class derived from ActiveViewModel: properties and [ActionMethod]
Quick start
Your first application in three steps
You need the .NET SDK 8 or 10. Important: the project uses the Microsoft.NET.Sdk.Web SDK – the “web” template sets it up that way.
-
Create the project, add the package
Create an empty web project and add the NuGet package IctBaden.Stonehenge4. To ship the views with the application, add the app folder to the project file.
Terminal
dotnet new web -n HelloStonehenge cd HelloStonehenge dotnet add package IctBaden.Stonehenge4*.csproj
<ItemGroup> <Content Include="app\**\*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> -
Start the server
Program.cs picks Vue.js as the client framework and Kestrel as the host. HostWindow opens the application as a desktop window; to run it as a web server, the program waits for Ctrl+C instead.
using IctBaden.Stonehenge.Hosting; using IctBaden.Stonehenge.Kestrel; using IctBaden.Stonehenge.Resources; using IctBaden.Stonehenge.Vue; using var loggerFactory = LoggerFactory.Create(b => b.AddConsole()); var logger = loggerFactory.CreateLogger("stonehenge"); var options = new StonehengeHostOptions { Title = "Hello Stonehenge", ServerPushMode = ServerPushModes.ServerSentEvents }; var vue = new VueResourceProvider(logger); var loader = StonehengeResourceLoader.CreateDefaultLoader(logger, vue); var host = new KestrelHost(loader, options); if (!host.Start("localhost", 32000)) return 1; // As a desktop app: own window, exits when closed using var window = new HostWindow(logger, host.BaseUrl, options.Title); window.Open(); host.Terminate(); return 0; -
Write the view and the view model
By convention the view app/start.html belongs to the class StartVm. Then dotnet run – the application is available at http://localhost:32000.
app/start.html
<!--ViewModel:StartVm--> <div> <p>Hello from {{ComputerName}}!</p> <p>Clicked: {{CountPressed}}</p> <button class="btn btn-primary" @click="ButtonPressed()"> Click me </button> </div>ViewModels/StartVm.cs
public class StartVm : ActiveViewModel { public string ComputerName => Environment.MachineName; public int CountPressed { get; private set; } [ActionMethod] public void ButtonPressed() { CountPressed++; } }
More in the “Getting started” guide and the reference in the repository. Read the guide (external link)
Building blocks
Ready-made components for applications in production
Besides the core, the NuGet package contains extensions for typical tasks in business and industrial applications.
-
TreeView
Tree view for hierarchies such as plants, folders or device groups.
-
Forms
Editable drop-down, date picker, splitter and error messages.
-
Charts
Charts based on C3: lines, bars, pies, gauges and Sankey.
-
Mermaid
Flow, sequence and state diagrams from text.
-
SyntaxHighlight
Editor with syntax highlighting for C# source code.
-
AppDialog
Modal dialogs and message boxes, controlled from the view model.
Your own components
Reusable building blocks consist of an HTML file and a class derived from StonehengeComponent. The file name becomes the HTML tag.
app/computer-info.html
<!--CustomElement:model-->
<!--ViewModel:ComputerInfo-->
<div class="card">
<p>{{model.Name}}</p>
</div> ComputerInfo.cs
public class ComputerInfo : StonehengeComponent
{
public string Name => Environment.MachineName;
} app/start.html
<computer-info :model="Info"></computer-info> AI-ready
Prepared for AI coding assistants
The repository contains an integration guide for AI coding agents: conventions, file layout, required patterns and typical pitfalls. Copied into your project as AGENTS.md, it lets the assistant write Stonehenge code that follows the rules of the framework.
Read the integration guide (external link)Technology
A proven stack, maintained since 2013
Four generations
-
Version 1
.NET Framework
ServiceStack and Knockout
-
Version 2
.NET Framework
Katana and Aurelia
-
Version 3
.NET Core 3.1
Kestrel, Aurelia, then Vue.js
-
Version 4
.NET 8 and .NET 10
Kestrel or IIS, Vue.js 2, no cookies
Frequently asked questions
What is Stonehenge 4?
An open-source framework for .NET that gives applications a web user interface based on the MVVM pattern: view models in C#, views in HTML. The application runs as a desktop window or as a web app.
Is Stonehenge free of charge?
Yes. Stonehenge is licensed under the MIT licence and may be used freely, including commercially. ICT Baden offers help getting started, extensions and custom development on request.
Which .NET versions are supported?
.NET 10 with package version 10.x and .NET 8 with package version 8.8.x. The project has to use the Microsoft.NET.Sdk.Web SDK; version 4 no longer supports the .NET Framework.
Do I need to know JavaScript?
No. Views are HTML with the template syntax of Vue.js 2 – for example {{Name}}, @click and v-for. Stonehenge serves the JavaScript part itself; your own scripts are possible but not required.
Does Stonehenge run as a desktop application?
Yes. HostWindow opens the application in its own window of an installed browser, such as Chrome, Edge, Brave, Firefox or Safari. The same application can also run as a web server for many users.
Why Vue.js 2 and not Vue 3?
The Bootstrap-Vue components in use do not support Vue 3 yet. Stonehenge therefore stays with Vue.js 2 and Bootstrap 5.
Contact
Stonehenge in your project?
We help you get started, build extensions or complete applications with Stonehenge – and answer questions about the framework.
Seboldstraße 9, 76227 Karlsruhe, Germany · Directions (PDF, German)