Web Quick Start preview
Hermes.Web lets you build desktop applications using any JavaScript or TypeScript framework — React, Vue, Svelte, Angular, or vanilla JS. Instead of Blazor, your UI runs as a standard web app inside the Hermes WebView, with full access to native desktop capabilities through the interop bridge.
When to use Hermes.Web vs Hermes.Blazor
Use Hermes.Web when your team already has a JavaScript/TypeScript frontend, when you want access to the broader JS ecosystem (Vite, ESLint, Tailwind, etc.), or when migrating an existing Electron app. Use Hermes.Blazor when you prefer an all-C# stack.
Prerequisites
- .NET 10 SDK
- Node.js 18+ and npm (for your frontend project)
- Platform-specific WebView requirements (see Installation)
Project Setup
Create a new console application and add the Hermes.Web package:
dotnet new console -n MyDesktopApp
cd MyDesktopApp
dotnet add package Mythetech.Hermes.WebScaffold a frontend project inside your app directory. This example uses Vite with vanilla TypeScript, but you can use any framework:
npm create vite@latest frontend -- --template vanilla-ts
cd frontend
npm install @hermes/bridgeProgram.cs
Replace your Program.cs with:
using Hermes;
using Hermes.Web;
HermesWindow.Prewarm();
var builder = HermesWebAppBuilder.Create(args);
builder.ConfigureWindow(opts =>
{
opts.Title = "My Desktop App";
opts.Width = 1024;
opts.Height = 768;
opts.CenterOnScreen = true;
opts.DevToolsEnabled = true;
});
#if DEBUG
builder.UseDevServer("http://localhost:5173");
#else
builder.UseStaticFiles("frontend/dist");
builder.UseSpaFallback();
#endif
builder.UseInteropBridge(bridge =>
{
bridge.Register<string, string>("greet", name => $"Hello from C#, {name}!");
bridge.Register("getRuntime", () => $".NET {Environment.Version}");
});
var app = builder.Build();
app.Run();Frontend Code
In your frontend's main.ts, use the bridge to call C# methods:
import { bridge } from '@hermes/bridge';
const result = await bridge.invoke<string>('greet', 'World');
console.log(result); // "Hello from C#, World!"Running in Development
Start the Vite dev server and the .NET app in separate terminals:
# Terminal 1 — frontend dev server
cd frontend
npm run dev
# Terminal 2 — .NET host
dotnet runThe Hermes window opens and connects to the Vite dev server. Hot module replacement works natively — edit your frontend code and see changes instantly.
Building for Production
Build the frontend, then publish the .NET app:
cd frontend
npm run build
cd ..
dotnet publish -c ReleaseIn Release mode, Hermes serves the built assets from frontend/dist via the custom scheme handler. No dev server required.
Content Hosting
Hermes.Web provides two modes for serving your frontend content:
| Mode | Method | Use Case |
|---|---|---|
| Dev Server | UseDevServer(url) | Development with HMR |
| Static Files | UseStaticFiles(path) | Production builds |
UseStaticFiles() with no argument defaults to wwwroot/. Pass a path like "frontend/dist" or "build" to match your framework's output directory.
UseSpaFallback() enables index.html fallback for client-side routing — without it, deep links return 404.
Window Options
Configure the native window through ConfigureWindow:
builder.ConfigureWindow(opts =>
{
opts.Title = "My App";
opts.Width = 1280;
opts.Height = 720;
opts.CenterOnScreen = true;
opts.Resizable = true;
opts.DevToolsEnabled = true;
// Size constraints
opts.MinWidth = 640;
opts.MinHeight = 480;
// Remember position/size between launches
opts.WindowStateKey = "main-window";
// Frameless window
opts.Chromeless = true;
opts.CustomTitleBar = true;
});See the full HermesWindow API for all available options.
Next Steps
- JavaScript Bridge — Deep dive into C# ↔ JS interop
- React Integration — Using the
@hermes/reactadapter - Windows Guide — Advanced window configuration
- Menus Guide — Native menu bars
