Run Controllers, Razor Views, EF Core, Identity, and SignalR entirely in the browser — no server required.
Architecture · SDK Design · CLI Design · Documentation · .NET 11 Proposal
ASP.NET Core today offers two client-side hosting models: Blazor Server (server-rendered, SignalR-connected) and Blazor WebAssembly (component-based SPA). Neither provides the Controller → Action → View pattern that millions of .NET developers know from MVC.
NetWasmMVCRuntime fills this gap. It is a reference implementation proving that the full MVC programming model — controllers, Razor views, model binding, action results — can execute entirely in WebAssembly, with no server dependency.
This repository serves as the technical foundation for a formal .NET 11 proposal to introduce client-side MVC as a complementary hosting model in ASP.NET Core.
<Project Sdk="NetWasmMvc.SDK/1.0.6">
<!-- Zero-config — Controllers, Views, EF Core, Identity, SignalR -->
<!-- All bundled. No PackageReferences needed. -->
</Project>A single <Project Sdk="..."> line gives you a complete MVC application running in the browser. The SDK bundles the runtime, Razor engine, EF Core with SQLite, Identity, and SignalR — all pre-configured for browser-wasm.
| Capability | What It Does |
|---|---|
| MVC Pipeline | Controller → Action → ViewResult → HTML executing in a Web Worker |
| Razor View Engine | .cshtml template processing without Roslyn compilation overhead |
| EF Core + SQLite | Entity Framework Core with SQLite persisted to OPFS (Origin Private File System) |
| Client-Side Identity | PBKDF2 password hashing, HMAC-signed sessions, fingerprint binding, account lockout |
| In-Process SignalR | Hub dispatch via reflection — real-time messaging without network transport |
| Dual Hosting | Same codebase runs as Browser SPA or Node.js/Edge API server |
| CLI Tooling | cepha CLI for scaffolding, dev server, benchmarks, and deployment |
┌─────────────────────────────────────────────────────────┐
│ Browser │
│ │
│ ┌──────────────┐ ┌────────────────────────────────┐ │
│ │ Main Thread │◄──►│ Runtime Worker │ │
│ │ (UI / DOM) │ │ ├─ MvcEngine │ │
│ │ │ │ ├─ RazorTemplateEngine │ │
│ │ Renders HTML │ │ ├─ ControllerInvoker │ │
│ │ returned by │ │ ├─ SignalREngine │ │
│ │ MVC pipeline │ │ └─ IdentityService │ │
│ └──────────────┘ └──────────┬─────────────────────┘ │
│ │ │
│ ┌──────────▼─────────────────────┐ │
│ │ Data Worker │ │
│ │ ├─ EF Core DbContext │ │
│ │ ├─ SQLite (e_sqlite3.a) │ │
│ │ └─ OPFS Persistence Layer │ │
│ └────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
| Thread | Responsibility | Key Types |
|---|---|---|
| Main | DOM rendering, user input, navigation interception | JsInterop, JsExports |
| Runtime Worker | MVC pipeline execution, controller dispatch, Razor rendering | MvcEngine, RazorTemplateEngine, SignalREngine |
| Data Worker | Database operations, OPFS file I/O | ApplicationDbContext, IdentityDbContext |
This three-thread architecture ensures the UI thread never blocks on MVC processing or database queries.
User clicks link
→ Main thread intercepts navigation (pushState)
→ Posts message to Runtime Worker
→ MvcEngine.ProcessRequest(url)
→ Resolves Controller + Action via reflection
→ Invokes action method
→ If ViewResult: RazorTemplateEngine.RenderView(viewName, viewData)
→ Returns rendered HTML string
→ Main thread receives HTML
→ Updates DOM via innerHTML
The NetWasmMvc.SDK is an MSBuild SDK that transforms a standard .NET project into a self-contained WebAssembly MVC application. It is designed as a reference for how client-side MVC could be integrated into the official .NET SDK.
NetWasmMvc.SDK/
├── Sdk/
│ ├── Sdk.props # Build configuration (TFM, runtime, WASM settings)
│ └── Sdk.targets # Auto-imports, DLL bundling, deployment targets
├── lib/
│ └── net10.0/
│ └── WasmMvcRuntime.Core.dll # Pre-compiled runtime (avoid recompilation)
├── shared/
│ ├── CephaApp.cs # Application bootstrap
│ ├── JsInterop.cs # Browser ↔ .NET bridge
│ ├── JsExports.cs # Exported methods for JS
│ └── SqliteNativeResolver.cs # SQLite native library resolver
├── content/
│ └── wwwroot/
│ ├── index.html # SPA shell
│ ├── main.js # Bootstrap + navigation
│ ├── cepha-runtime-worker.js # MVC pipeline worker
│ └── cepha-data-worker.js # Database worker
└── deploy/
├── local/ # Local dev server
├── cloudflare/ # Cloudflare Pages config
└── azure/ # Azure Static Web Apps config
- Zero-Config: A single
<Project Sdk="NetWasmMvc.SDK/1.0.6">line is enough. NoPackageReferencenodes needed. - Convention over Configuration: Controllers in
Controllers/, Views inViews/{ControllerName}/, Models inModels/. - Pre-compiled Runtime: The SDK bundles pre-compiled DLLs to avoid recompiling the runtime on every build.
- Deployment Targets: Built-in MSBuild targets for local, Cloudflare Pages, and Azure Static Web Apps deployment.
- Extensible: Developers can override any default by setting MSBuild properties in their
.csproj.
<!-- Simplified view of what Sdk.props configures -->
<Import Sdk="Microsoft.NET.Sdk.WebAssembly" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup><!-- Simplified view of what Sdk.targets provides -->
<!-- 1. Auto-import runtime DLLs -->
<Reference Include="WasmMvcRuntime.Abstractions" HintPath="$(SdkPath)/lib/..." />
<Reference Include="WasmMvcRuntime.Core" HintPath="$(SdkPath)/lib/..." />
<!-- 2. Embed .cshtml files as resources -->
<EmbeddedResource Include="Views/**/*.cshtml" />
<!-- 3. Include SQLite native for browser-wasm -->
<NativeFileReference Include="e_sqlite3.a" />
<!-- 4. Auto-generate global usings -->
<Using Include="WasmMvcRuntime.Abstractions" />
<Using Include="WasmMvcRuntime.Core" />The Cepha CLI (cepha) is a .NET global tool for scaffolding, running, and deploying NetWasmMVC applications. It is designed as a reference for how dotnet new wasmmvc could work in the official .NET CLI.
Cepha.CLI/
├── Program.cs # Entry point, interactive menu
├── Commands/
│ ├── NewCommand.cs # Project scaffolding
│ ├── RunCommand.cs # Dev server launcher
│ ├── BuildCommand.cs # Build orchestration
│ ├── DeployCommand.cs # Deployment automation
│ └── BenchmarkCommand.cs # Framework comparison benchmarks
├── Services/
│ ├── SdkResolver.cs # Dynamic SDK version discovery
│ ├── TemplateEngine.cs # Project template rendering
│ └── ServerManager.cs # Dev server lifecycle
├── Templates/
│ ├── default/ # Standard MVC template
│ └── identity/ # MVC + Identity template
└── UI/
└── ConsoleUI.cs # Interactive menu system
# Install
dotnet tool install --global Cepha.CLI
# Scaffold a new project
cepha new my-app # Default MVC template
cepha new my-app --template identity # MVC + Identity template
# Development
cepha run # Start dev server with hot reload
cepha build # Build for production
# Deployment
cepha deploy local # Serve locally
cepha deploy cloudflare # Deploy to Cloudflare Pages
cepha deploy azure # Deploy to Azure Static Web Apps
# Benchmarks
cepha benchmark # Compare Cepha vs React vs Vue vs Vanillacepha new my-app
→ Resolves latest SDK version from NuGet
→ Creates project directory
→ Generates .csproj with Sdk="NetWasmMvc.SDK/{version}"
→ Scaffolds Controllers/HomeController.cs
→ Scaffolds Views/Home/Index.cshtml
→ Scaffolds Program.cs (entry point)
→ Runs dotnet restore
→ Ready to build and run
| Library | Purpose | Key Types |
|---|---|---|
WasmMvcRuntime.Abstractions |
Contracts and base classes | Controller, IActionResult, ViewResult, WasmHttpContext |
WasmMvcRuntime.Core |
Engine implementations | MvcEngine, RazorTemplateEngine, SignalREngine |
WasmMvcRuntime.Identity |
Authentication & authorization | UserManager, SignInManager, IdentityAtom, SessionStorageService |
WasmMvcRuntime.Data |
Data access layer | ApplicationDbContext, BackupService, Cloud providers |
WasmMvcRuntime.App |
Reference application | Controllers, Models, Hubs, Repositories |
WasmMvcRuntime.Client |
Browser host (SPA) | Entry point, JS interop, service registration |
WasmMvcRuntime.Cepha |
Node.js host (Server) | CephaServer, SSE, CephaKit integration |
- .NET 10 SDK or later
dotnet tool install --global Cepha.CLI
cepha new my-app
cd my-app
cepha run<!-- my-app.csproj -->
<Project Sdk="NetWasmMvc.SDK/1.0.6">
</Project>// Controllers/HomeController.cs
using WasmMvcRuntime.Abstractions;
public class HomeController : Controller
{
public IActionResult Index()
{
ViewData["Title"] = "Home";
ViewData["Message"] = "Running in WebAssembly!";
return View();
}
}dotnet build && dotnet rungit clone https://github.com/sbay-dev/NetWasmMVCRuntime.git
cd NetWasmMVCRuntime
dotnet restore
dotnet buildNote:
WasmMvcRuntime.ClientandWasmMvcRuntime.CephauseCepha.Sdkas their MSBuild SDK. The required package is inlocal-packages/and resolved vianuget.config.
NetWasmMVCRuntime/
├── WasmMvcRuntime.Abstractions/ # Contracts: Controller, IActionResult, ViewResult
├── WasmMvcRuntime.Core/ # Engines: MvcEngine, Razor, SignalR
├── WasmMvcRuntime.Identity/ # Identity: UserManager, PBKDF2, HMAC sessions
├── WasmMvcRuntime.Data/ # Data: EF Core, SQLite WASM, cloud providers
├── WasmMvcRuntime.App/ # Reference app: controllers, models, hubs
├── WasmMvcRuntime.Client/ # Browser host (Blazor WASM entry point)
├── WasmMvcRuntime.Cepha/ # Node.js host (CephaKit server entry point)
├── NetWasmMvc.SDK/ # MSBuild SDK — zero-config project template
├── Cepha.Sdk/ # Internal build SDK
├── Cepha.CLI/ # CLI tool for scaffolding and deployment
├── samples/ # Sample applications
├── docs/ # Architecture, security, proposal, landing page
└── local-packages/ # Pre-built SDK NuGet packages for local build
| Document | Description |
|---|---|
| Architecture | Runtime architecture, thread model, rendering pipeline |
| Hosting Models | Browser SPA, Node.js, Edge Workers, Embedded WebView |
| Security Model | Identity system, cryptographic primitives, threat model |
| CLI Reference | Cepha CLI commands and workflows |
| Roadmap | Current state and planned features |
| .NET 11 Proposal | Formal proposal for ASP.NET Core integration |
This project proposes adding client-side MVC as an experimental hosting model in .NET 11, complementing Blazor rather than replacing it.
| Ask | Description |
|---|---|
| Recognize | Client-side MVC as a valid WebAssembly hosting model |
| Template | dotnet new wasmmvc project template |
| Package | Microsoft.AspNetCore.Mvc.WebAssembly experimental package |
| Razor Target | Enable Razor view compilation targeting browser-wasm |
| SDK Integration | Evaluate NetWasmMvc.SDK patterns for official SDK |
| Scenario | Blazor | Client-Side MVC |
|---|---|---|
| Component-based UI | ✅ Primary model | ❌ Not the goal |
| Page-based navigation | ✅ Native pattern | |
| Server-rendered feel | ❌ Different model | ✅ Controller → View |
| Existing MVC migration | ❌ Requires rewrite | ✅ Familiar pattern |
| Offline-first apps | ✅ Full OPFS persistence |
This project is designed to meet .NET Foundation membership criteria:
- ✅ MIT License — permissive, foundation-compatible
- ✅ CI/CD Pipeline — GitHub Actions for build, test, publish
- ✅ NuGet Packages — SDK and CLI published to nuget.org
- ✅ Comprehensive Documentation — architecture, security model, hosting models, roadmap
- ✅ Security Model — documented threat model, cryptographic primitives, session management
- ✅ Code of Conduct — contributor guidelines in CONTRIBUTING.md
- ✅ Semantic Versioning — CHANGELOG.md following Keep a Changelog format
- ✅ Cross-Platform — targets
browser-wasm, runs on Windows/Linux/macOS
See CONTRIBUTING.md for guidelines.
MIT License — see LICENSE for details.
NetWasmMVCRuntime — Bringing the full ASP.NET MVC experience to WebAssembly.
A reference implementation for client-side MVC in .NET · sbay-dev